]>
Commit | Line | Data |
---|---|---|
b64b3086 | 1 | /* sexp-transport.c |
90112edb NM |
2 | |
3 | Parsing s-expressions in transport format. | |
4 | ||
5 | Copyright (C) 2002 Niels Möller | |
6 | ||
7 | This file is part of GNU Nettle. | |
8 | ||
9 | GNU Nettle is free software: you can redistribute it and/or | |
10 | modify it under the terms of either: | |
11 | ||
12 | * the GNU Lesser General Public License as published by the Free | |
13 | Software Foundation; either version 3 of the License, or (at your | |
14 | option) any later version. | |
15 | ||
16 | or | |
17 | ||
18 | * the GNU General Public License as published by the Free | |
19 | Software Foundation; either version 2 of the License, or (at your | |
20 | option) any later version. | |
21 | ||
22 | or both in parallel, as here. | |
23 | ||
24 | GNU Nettle is distributed in the hope that it will be useful, | |
25 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
27 | General Public License for more details. | |
28 | ||
29 | You should have received copies of the GNU General Public License and | |
30 | the GNU Lesser General Public License along with this program. If | |
31 | not, see http://www.gnu.org/licenses/. | |
32 | */ | |
b64b3086 | 33 | |
c5c15385 NM |
34 | #if HAVE_CONFIG_H |
35 | # include "config.h" | |
36 | #endif | |
b64b3086 NM |
37 | |
38 | #include <assert.h> | |
39 | #include <string.h> | |
40 | ||
c5c15385 NM |
41 | #include "sexp.h" |
42 | ||
43 | #include "base64.h" | |
44 | ||
b64b3086 NM |
45 | /* NOTE: Decodes the input string in place */ |
46 | int | |
47 | sexp_transport_iterator_first(struct sexp_iterator *iterator, | |
86fdb2ce | 48 | size_t length, uint8_t *input) |
b64b3086 NM |
49 | { |
50 | /* We first base64 decode any transport encoded sexp at the start of | |
51 | * the input. */ | |
52 | ||
86fdb2ce NM |
53 | size_t in = 0; |
54 | size_t out = 0; | |
b64b3086 NM |
55 | |
56 | while (in < length) | |
57 | switch(input[in]) | |
58 | { | |
59 | case ' ': /* SPC, TAB, LF, CR */ | |
60 | case '\t': | |
61 | case '\n': | |
62 | case '\r': | |
63 | in++; | |
64 | break; | |
65 | ||
66 | case ';': /* Comments */ | |
67 | while (++in < length && input[in] != '\n') | |
68 | ; | |
69 | break; | |
70 | ||
71 | case '{': | |
72 | { | |
73 | /* Found transport encoding */ | |
74 | struct base64_decode_ctx ctx; | |
86fdb2ce NM |
75 | size_t coded_length; |
76 | size_t end; | |
b64b3086 NM |
77 | |
78 | for (end = ++in; end < length && input[end] != '}'; end++) | |
79 | ; | |
80 | ||
81 | if (end == length) | |
82 | return 0; | |
83 | ||
84 | base64_decode_init(&ctx); | |
e0292d52 | 85 | |
38f1828d | 86 | if (base64_decode_update(&ctx, &coded_length, input + out, |
f2da4031 | 87 | end - in, (const char*) (input + in)) |
e0292d52 NM |
88 | && base64_decode_final(&ctx)) |
89 | { | |
38f1828d | 90 | out += coded_length; |
e0292d52 NM |
91 | in = end + 1; |
92 | } | |
93 | else | |
b64b3086 | 94 | return 0; |
e0292d52 | 95 | |
b64b3086 NM |
96 | break; |
97 | } | |
98 | default: | |
99 | /* Expression isn't in transport encoding. Rest of the input | |
100 | * should be in canonical encoding. */ | |
101 | goto transport_done; | |
102 | } | |
103 | ||
104 | transport_done: | |
105 | ||
106 | /* Here, we have two, possibly empty, input parts in canonical | |
107 | * encoding: | |
108 | * | |
109 | * 0...out-1, in...length -1 | |
110 | * | |
111 | * If the input was already in canonical encoding, out = 0 and in = | |
112 | * amount of leading space. | |
113 | * | |
114 | * If all input was in transport encoding, in == length. | |
115 | */ | |
116 | if (!out) | |
117 | { | |
118 | input += in; | |
119 | length -= in; | |
120 | } | |
121 | else if (in == length) | |
122 | length = out; | |
123 | else if (out == in) | |
124 | /* Unusual case, nothing happens */ | |
125 | ; | |
126 | else | |
127 | { | |
128 | /* Both parts non-empty */ | |
129 | assert(out < in); | |
130 | memmove(input + out, input + in, length - in); | |
131 | length -= (in - out); | |
132 | } | |
133 | ||
134 | return sexp_iterator_first(iterator, length, input); | |
135 | } |