blob: 9391316883249c7230d4f324a99a5653d35cacf2 [file] [log] [blame]
Lev Walkinf15320b2004-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 */
Lev Walkind9bd7752004-06-05 08:17:50 +000024 0, /* Always in primitive form */
25 0 /* No specifics */
Lev Walkinf15320b2004-06-03 03:38:44 +000026};
27
28/*
29 * Decode BOOLEAN type.
30 */
31ber_dec_rval_t
32BOOLEAN_decode_ber(asn1_TYPE_descriptor_t *td,
33 void **bool_structure, void *buf_ptr, size_t size,
34 int tag_mode) {
35 BOOLEAN_t *st = *bool_structure;
36 ber_dec_rval_t rval;
Lev Walkind9bd7752004-06-05 08:17:50 +000037 ber_dec_ctx_t ctx = { 0, 0, 0, 0 };
Lev Walkinf15320b2004-06-03 03:38:44 +000038 ber_tlv_len_t length;
39 ber_tlv_len_t lidx;
40
41 if(st == NULL) {
42 st = *bool_structure = CALLOC(1, sizeof(*st));
43 if(st == NULL) {
44 rval.code = RC_FAIL;
45 rval.consumed = 0;
46 return rval;
47 }
48 }
49
50 ASN_DEBUG("Decoding %s as BOOLEAN (tm=%d)",
51 td->name, tag_mode);
52
53 /*
54 * Check tags.
55 */
56 rval = ber_check_tags(td, &ctx,
57 buf_ptr, size, tag_mode, &length, 0);
58 if(rval.code != RC_OK)
59 return rval;
60
61 ASN_DEBUG("Boolean length is %d bytes", (int)length);
62
63 buf_ptr += rval.consumed;
64 size -= rval.consumed;
Lev Walkind9bd7752004-06-05 08:17:50 +000065 if(length > (ber_tlv_len_t)size) {
Lev Walkinf15320b2004-06-03 03:38:44 +000066 rval.code = RC_WMORE;
67 rval.consumed = 0;
68 return rval;
69 }
70
71 /*
72 * Compute boolean value.
73 */
74 for(st->value = 0, lidx = 0;
75 (lidx < length) && st->value == 0; lidx++) {
76 /*
77 * Very simple approach: read bytes until the end or
78 * value is already TRUE.
79 * BOOLEAN is not supposed to contain meaningful data anyway.
80 */
81 st->value |= ((uint8_t *)buf_ptr)[lidx];
82 }
83
84 rval.code = RC_OK;
85 rval.consumed += length;
86
87 ASN_DEBUG("Took %ld/%ld bytes to encode %s, value=%ld",
88 (long)rval.consumed, (long)length,
89 td->name, (long)st->value);
90
91 return rval;
92}
93
94der_enc_rval_t
95BOOLEAN_encode_der(asn1_TYPE_descriptor_t *td, void *sptr,
96 int tag_mode, ber_tlv_tag_t tag,
97 asn_app_consume_bytes_f *cb, void *app_key) {
98 der_enc_rval_t erval;
99 BOOLEAN_t *st = sptr;
100
101 erval.encoded = der_write_tags(td, 1, tag_mode, tag, cb, app_key);
102 if(erval.encoded == -1) {
103 erval.failed_type = td;
104 erval.structure_ptr = sptr;
105 return erval;
106 }
107
108 if(cb) {
109 uint8_t bool_value;
110 ssize_t ret;
111
112 bool_value = st->value?0xff:0; /* 0xff mandated by DER */
113 ret = cb(&bool_value, 1, app_key);
114 if(ret == -1) {
115 erval.encoded = -1;
116 erval.failed_type = td;
117 erval.structure_ptr = sptr;
118 return erval;
119 }
120 }
121
122 erval.encoded += 1;
123
124 return erval;
125}
126
127int
128BOOLEAN_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
129 asn_app_consume_bytes_f *cb, void *app_key) {
130 const BOOLEAN_t *st = sptr;
131
Lev Walkind9bd7752004-06-05 08:17:50 +0000132 (void)td; /* Unused argument */
133 (void)ilevel; /* Unused argument */
134
Lev Walkinf15320b2004-06-03 03:38:44 +0000135 if(st) {
136 if(st->value)
137 return cb("TRUE", 4, app_key);
138 else
139 return cb("FALSE", 5, app_key);
140 } else {
141 return cb("<absent>", 8, app_key);
142 }
143}
144
145void
146BOOLEAN_free(asn1_TYPE_descriptor_t *td, void *ptr, int contents_only) {
147 if(td && ptr && !contents_only) {
148 FREEMEM(ptr);
149 }
150}
151