blob: 705d37e0f13ac440a6cb674525a4682d3a2186e6 [file] [log] [blame]
vlmfa67ddc2004-06-03 03:38:44 +00001/*-
2 * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved.
3 * Redistribution and modifications are permitted subject to BSD license.
4 */
5#include <BOOLEAN.h>
6
7/*
8 * BOOLEAN basic type description.
9 */
10static ber_tlv_tag_t asn1_DEF_BOOLEAN_tags[] = {
11 (ASN_TAG_CLASS_UNIVERSAL | (1 << 2))
12};
13asn1_TYPE_descriptor_t asn1_DEF_BOOLEAN = {
14 "BOOLEAN",
15 asn_generic_no_constraint,
16 BOOLEAN_decode_ber,
17 BOOLEAN_encode_der,
18 BOOLEAN_print,
19 BOOLEAN_free,
20 0, /* Use generic outmost tag fetcher */
21 asn1_DEF_BOOLEAN_tags,
22 sizeof(asn1_DEF_BOOLEAN_tags)/sizeof(asn1_DEF_BOOLEAN_tags[0]),
23 1, /* Single UNIVERSAL tag may be implicitly overriden */
24 0 /* Always in primitive form */
25};
26
27/*
28 * Decode BOOLEAN type.
29 */
30ber_dec_rval_t
31BOOLEAN_decode_ber(asn1_TYPE_descriptor_t *td,
32 void **bool_structure, void *buf_ptr, size_t size,
33 int tag_mode) {
34 BOOLEAN_t *st = *bool_structure;
35 ber_dec_rval_t rval;
36 ber_dec_ctx_t ctx = { 0 };
37 ber_tlv_len_t length;
38 ber_tlv_len_t lidx;
39
40 if(st == NULL) {
41 st = *bool_structure = CALLOC(1, sizeof(*st));
42 if(st == NULL) {
43 rval.code = RC_FAIL;
44 rval.consumed = 0;
45 return rval;
46 }
47 }
48
49 ASN_DEBUG("Decoding %s as BOOLEAN (tm=%d)",
50 td->name, tag_mode);
51
52 /*
53 * Check tags.
54 */
55 rval = ber_check_tags(td, &ctx,
56 buf_ptr, size, tag_mode, &length, 0);
57 if(rval.code != RC_OK)
58 return rval;
59
60 ASN_DEBUG("Boolean length is %d bytes", (int)length);
61
62 buf_ptr += rval.consumed;
63 size -= rval.consumed;
64 if(length > size) {
65 rval.code = RC_WMORE;
66 rval.consumed = 0;
67 return rval;
68 }
69
70 /*
71 * Compute boolean value.
72 */
73 for(st->value = 0, lidx = 0;
74 (lidx < length) && st->value == 0; lidx++) {
75 /*
76 * Very simple approach: read bytes until the end or
77 * value is already TRUE.
78 * BOOLEAN is not supposed to contain meaningful data anyway.
79 */
80 st->value |= ((uint8_t *)buf_ptr)[lidx];
81 }
82
83 rval.code = RC_OK;
84 rval.consumed += length;
85
86 ASN_DEBUG("Took %ld/%ld bytes to encode %s, value=%ld",
87 (long)rval.consumed, (long)length,
88 td->name, (long)st->value);
89
90 return rval;
91}
92
93der_enc_rval_t
94BOOLEAN_encode_der(asn1_TYPE_descriptor_t *td, void *sptr,
95 int tag_mode, ber_tlv_tag_t tag,
96 asn_app_consume_bytes_f *cb, void *app_key) {
97 der_enc_rval_t erval;
98 BOOLEAN_t *st = sptr;
99
100 erval.encoded = der_write_tags(td, 1, tag_mode, tag, cb, app_key);
101 if(erval.encoded == -1) {
102 erval.failed_type = td;
103 erval.structure_ptr = sptr;
104 return erval;
105 }
106
107 if(cb) {
108 uint8_t bool_value;
109 ssize_t ret;
110
111 bool_value = st->value?0xff:0; /* 0xff mandated by DER */
112 ret = cb(&bool_value, 1, app_key);
113 if(ret == -1) {
114 erval.encoded = -1;
115 erval.failed_type = td;
116 erval.structure_ptr = sptr;
117 return erval;
118 }
119 }
120
121 erval.encoded += 1;
122
123 return erval;
124}
125
126int
127BOOLEAN_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
128 asn_app_consume_bytes_f *cb, void *app_key) {
129 const BOOLEAN_t *st = sptr;
130
131 if(st) {
132 if(st->value)
133 return cb("TRUE", 4, app_key);
134 else
135 return cb("FALSE", 5, app_key);
136 } else {
137 return cb("<absent>", 8, app_key);
138 }
139}
140
141void
142BOOLEAN_free(asn1_TYPE_descriptor_t *td, void *ptr, int contents_only) {
143 if(td && ptr && !contents_only) {
144 FREEMEM(ptr);
145 }
146}
147