source: azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/base64.c@ 398

Last change on this file since 398 was 398, checked in by coas-nagasima, 5 years ago

mbedTLS版Azure IoT Hub接続サンプルのソースコードを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 7.5 KB
Line 
1/*
2 * RFC 1521 base64 encoding/decoding
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22#if !defined(MBEDTLS_CONFIG_FILE)
23#include "mbedtls/config.h"
24#else
25#include MBEDTLS_CONFIG_FILE
26#endif
27
28#if defined(MBEDTLS_BASE64_C)
29
30#include "mbedtls/base64.h"
31
32#include <stdint.h>
33
34#if defined(MBEDTLS_SELF_TEST)
35#include <string.h>
36#if defined(MBEDTLS_PLATFORM_C)
37#include "mbedtls/platform.h"
38#else
39#include <stdio.h>
40#define mbedtls_printf printf
41#endif /* MBEDTLS_PLATFORM_C */
42#endif /* MBEDTLS_SELF_TEST */
43
44static const unsigned char base64_enc_map[64] =
45{
46 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
47 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
48 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
49 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
50 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
51 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
52 '8', '9', '+', '/'
53};
54
55static const unsigned char base64_dec_map[128] =
56{
57 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
58 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
59 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
60 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
61 127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
62 54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
63 127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
64 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
65 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
66 25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
67 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
68 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
69 49, 50, 51, 127, 127, 127, 127, 127
70};
71
72#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
73
74/*
75 * Encode a buffer into base64 format
76 */
77int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
78 const unsigned char *src, size_t slen )
79{
80 size_t i, n;
81 int C1, C2, C3;
82 unsigned char *p;
83
84 if( slen == 0 )
85 {
86 *olen = 0;
87 return( 0 );
88 }
89
90 n = slen / 3 + ( slen % 3 != 0 );
91
92 if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 )
93 {
94 *olen = BASE64_SIZE_T_MAX;
95 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
96 }
97
98 n *= 4;
99
100 if( ( dlen < n + 1 ) || ( NULL == dst ) )
101 {
102 *olen = n + 1;
103 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
104 }
105
106 n = ( slen / 3 ) * 3;
107
108 for( i = 0, p = dst; i < n; i += 3 )
109 {
110 C1 = *src++;
111 C2 = *src++;
112 C3 = *src++;
113
114 *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
115 *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
116 *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
117 *p++ = base64_enc_map[C3 & 0x3F];
118 }
119
120 if( i < slen )
121 {
122 C1 = *src++;
123 C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
124
125 *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
126 *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
127
128 if( ( i + 1 ) < slen )
129 *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
130 else *p++ = '=';
131
132 *p++ = '=';
133 }
134
135 *olen = p - dst;
136 *p = 0;
137
138 return( 0 );
139}
140
141/*
142 * Decode a base64-formatted buffer
143 */
144int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
145 const unsigned char *src, size_t slen )
146{
147 size_t i, n;
148 uint32_t j, x;
149 unsigned char *p;
150
151 /* First pass: check for validity and get output length */
152 for( i = n = j = 0; i < slen; i++ )
153 {
154 /* Skip spaces before checking for EOL */
155 x = 0;
156 while( i < slen && src[i] == ' ' )
157 {
158 ++i;
159 ++x;
160 }
161
162 /* Spaces at end of buffer are OK */
163 if( i == slen )
164 break;
165
166 if( ( slen - i ) >= 2 &&
167 src[i] == '\r' && src[i + 1] == '\n' )
168 continue;
169
170 if( src[i] == '\n' )
171 continue;
172
173 /* Space inside a line is an error */
174 if( x != 0 )
175 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
176
177 if( src[i] == '=' && ++j > 2 )
178 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
179
180 if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
181 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
182
183 if( base64_dec_map[src[i]] < 64 && j != 0 )
184 return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
185
186 n++;
187 }
188
189 if( n == 0 )
190 {
191 *olen = 0;
192 return( 0 );
193 }
194
195 /* The following expression is to calculate the following formula without
196 * risk of integer overflow in n:
197 * n = ( ( n * 6 ) + 7 ) >> 3;
198 */
199 n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 );
200 n -= j;
201
202 if( dst == NULL || dlen < n )
203 {
204 *olen = n;
205 return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
206 }
207
208 for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
209 {
210 if( *src == '\r' || *src == '\n' || *src == ' ' )
211 continue;
212
213 j -= ( base64_dec_map[*src] == 64 );
214 x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F );
215
216 if( ++n == 4 )
217 {
218 n = 0;
219 if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
220 if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
221 if( j > 2 ) *p++ = (unsigned char)( x );
222 }
223 }
224
225 *olen = p - dst;
226
227 return( 0 );
228}
229
230#if defined(MBEDTLS_SELF_TEST)
231
232static const unsigned char base64_test_dec[64] =
233{
234 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
235 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
236 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
237 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
238 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
239 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
240 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
241 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
242};
243
244static const unsigned char base64_test_enc[] =
245 "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
246 "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
247
248/*
249 * Checkup routine
250 */
251int mbedtls_base64_self_test( int verbose )
252{
253 size_t len;
254 const unsigned char *src;
255 unsigned char buffer[128];
256
257 if( verbose != 0 )
258 mbedtls_printf( " Base64 encoding test: " );
259
260 src = base64_test_dec;
261
262 if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 ||
263 memcmp( base64_test_enc, buffer, 88 ) != 0 )
264 {
265 if( verbose != 0 )
266 mbedtls_printf( "failed\n" );
267
268 return( 1 );
269 }
270
271 if( verbose != 0 )
272 mbedtls_printf( "passed\n Base64 decoding test: " );
273
274 src = base64_test_enc;
275
276 if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 ||
277 memcmp( base64_test_dec, buffer, 64 ) != 0 )
278 {
279 if( verbose != 0 )
280 mbedtls_printf( "failed\n" );
281
282 return( 1 );
283 }
284
285 if( verbose != 0 )
286 mbedtls_printf( "passed\n\n" );
287
288 return( 0 );
289}
290
291#endif /* MBEDTLS_SELF_TEST */
292
293#endif /* MBEDTLS_BASE64_C */
Note: See TracBrowser for help on using the repository browser.