suricata
util-base64.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2012 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author David Abarbanel <david.abarbanel@baesystems.com>
22  *
23  */
24 
25 #include "util-base64.h"
26 
27 /* Constants */
28 #define BASE64_TABLE_MAX 122
29 
30 /* Base64 character to index conversion table */
31 /* Characters are mapped as "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" */
32 static const int b64table[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
33  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
34  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
35  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
36  -1, -1, -1, 62, -1, -1, -1, 63, 52, 53,
37  54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
38  -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
39  5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
40  15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
41  25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
42  29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
43  39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
44  49, 50, 51 };
45 
46 /**
47  * \brief Gets a base64-decoded value from an encoded character
48  *
49  * \param c The encoded character
50  *
51  * \return The decoded value (0 or above), or -1 if the parameter is invalid
52  */
53 static inline int GetBase64Value(uint8_t c)
54 {
55  int val = -1;
56 
57  /* Pull from conversion table */
58  if (c <= BASE64_TABLE_MAX) {
59  val = b64table[(int) c];
60  }
61 
62  return val;
63 }
64 
65 /**
66  * \brief Decodes a 4-byte base64-encoded block into a 3-byte ascii-encoded block
67  *
68  * \param ascii the 3-byte ascii output block
69  * \param b64 the 4-byte base64 input block
70  *
71  * \return none
72  */
73 static inline void DecodeBase64Block(uint8_t ascii[ASCII_BLOCK], uint8_t b64[B64_BLOCK])
74 {
75  ascii[0] = (uint8_t) (b64[0] << 2) | (b64[1] >> 4);
76  ascii[1] = (uint8_t) (b64[1] << 4) | (b64[2] >> 2);
77  ascii[2] = (uint8_t) (b64[2] << 6) | (b64[3]);
78 }
79 
80 /**
81  * \brief Decodes a base64-encoded string buffer into an ascii-encoded byte buffer
82  *
83  * \param dest The destination byte buffer
84  * \param src The source string
85  * \param len The length of the source string
86  * \param strict If set file on invalid byte, otherwise return what has been
87  * decoded.
88  *
89  * \return Number of bytes decoded, or 0 if no data is decoded or it fails
90  */
91 uint32_t DecodeBase64(uint8_t *dest, const uint8_t *src, uint32_t len,
92  int strict)
93 {
94  int val;
95  uint32_t padding = 0, numDecoded = 0, bbidx = 0, valid = 1, i;
96  uint8_t *dptr = dest;
97  uint8_t b64[B64_BLOCK] = { 0,0,0,0 };
98 
99  /* Traverse through each alpha-numeric letter in the source array */
100  for(i = 0; i < len && src[i] != 0; i++) {
101 
102  /* Get decimal representation */
103  val = GetBase64Value(src[i]);
104  if (val < 0) {
105 
106  /* Invalid character found, so decoding fails */
107  if (src[i] != '=') {
108  valid = 0;
109  if (strict) {
110  numDecoded = 0;
111  }
112  break;
113  }
114  padding++;
115  }
116 
117  /* For each alpha-numeric letter in the source array, find the numeric
118  * value */
119  b64[bbidx++] = (val > 0 ? val : 0);
120 
121  /* Decode every 4 base64 bytes into 3 ascii bytes */
122  if (bbidx == B64_BLOCK) {
123 
124  /* For every 4 bytes, add 3 bytes but deduct the '=' padded blocks */
125  numDecoded += ASCII_BLOCK - (padding < B64_BLOCK ?
126  padding : ASCII_BLOCK);
127 
128  /* Decode base-64 block into ascii block and move pointer */
129  DecodeBase64Block(dptr, b64);
130  dptr += ASCII_BLOCK;
131 
132  /* Reset base-64 block and index */
133  bbidx = 0;
134  padding = 0;
135  }
136  }
137 
138  /* Finish remaining b64 bytes by padding */
139  if (valid && bbidx > 0) {
140 
141  /* Decode remaining */
142  numDecoded += ASCII_BLOCK - (B64_BLOCK - bbidx);
143  DecodeBase64Block(dptr, b64);
144  }
145 
146  if (numDecoded == 0) {
147  SCLogDebug("base64 decoding failed");
148  }
149 
150  return numDecoded;
151 }
#define SCLogDebug(...)
Definition: util-debug.h:335
uint16_t src
#define ASCII_BLOCK
Definition: util-base64.h:48
uint32_t padding
Definition: decode-erspan.h:49
#define BASE64_TABLE_MAX
Definition: util-base64.c:28
uint8_t len
uint32_t DecodeBase64(uint8_t *dest, const uint8_t *src, uint32_t len, int strict)
Decodes a base64-encoded string buffer into an ascii-encoded byte buffer.
Definition: util-base64.c:91
#define B64_BLOCK
Definition: util-base64.h:49