Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

474 linhas
13 KiB

  1. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  2. * All rights reserved.
  3. *
  4. * This package is an SSL implementation written
  5. * by Eric Young (eay@cryptsoft.com).
  6. * The implementation was written so as to conform with Netscapes SSL.
  7. *
  8. * This library is free for commercial and non-commercial use as long as
  9. * the following conditions are aheared to. The following conditions
  10. * apply to all code found in this distribution, be it the RC4, RSA,
  11. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  12. * included with this distribution is covered by the same copyright terms
  13. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  14. *
  15. * Copyright remains Eric Young's, and as such any Copyright notices in
  16. * the code are not to be removed.
  17. * If this package is used in a product, Eric Young should be given attribution
  18. * as the author of the parts of the library used.
  19. * This can be in the form of a textual message at program startup or
  20. * in documentation (online or textual) provided with the package.
  21. *
  22. * Redistribution and use in source and binary forms, with or without
  23. * modification, are permitted provided that the following conditions
  24. * are met:
  25. * 1. Redistributions of source code must retain the copyright
  26. * notice, this list of conditions and the following disclaimer.
  27. * 2. Redistributions in binary form must reproduce the above copyright
  28. * notice, this list of conditions and the following disclaimer in the
  29. * documentation and/or other materials provided with the distribution.
  30. * 3. All advertising materials mentioning features or use of this software
  31. * must display the following acknowledgement:
  32. * "This product includes cryptographic software written by
  33. * Eric Young (eay@cryptsoft.com)"
  34. * The word 'cryptographic' can be left out if the rouines from the library
  35. * being used are not cryptographic related :-).
  36. * 4. If you include any Windows specific code (or a derivative thereof) from
  37. * the apps directory (application code) you must include an acknowledgement:
  38. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  39. *
  40. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  41. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  42. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  43. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  44. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  45. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  46. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  48. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  49. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  50. * SUCH DAMAGE.
  51. *
  52. * The licence and distribution terms for any publically available version or
  53. * derivative of this code cannot be changed. i.e. this code cannot simply be
  54. * copied and put under another distribution licence
  55. * [including the GNU Public Licence.] */
  56. #include <openssl/base64.h>
  57. #include <assert.h>
  58. #include <limits.h>
  59. static const unsigned char data_bin2ascii[65] =
  60. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  61. #define conv_bin2ascii(a) (data_bin2ascii[(a) & 0x3f])
  62. /* 64 char lines
  63. * pad input with 0
  64. * left over chars are set to =
  65. * 1 byte => xx==
  66. * 2 bytes => xxx=
  67. * 3 bytes => xxxx
  68. */
  69. #define BIN_PER_LINE (64/4*3)
  70. #define CHUNKS_PER_LINE (64/4)
  71. #define CHAR_PER_LINE (64+1)
  72. /* 0xF0 is a EOLN
  73. * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
  74. * 0xF2 is EOF
  75. * 0xE0 is ignore at start of line.
  76. * 0xFF is error */
  77. #define B64_EOLN 0xF0
  78. #define B64_CR 0xF1
  79. #define B64_EOF 0xF2
  80. #define B64_WS 0xE0
  81. #define B64_ERROR 0xFF
  82. #define B64_NOT_BASE64(a) (((a) | 0x13) == 0xF3)
  83. static const uint8_t data_ascii2bin[128] = {
  84. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xF0, 0xFF,
  85. 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  86. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF,
  87. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
  88. 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
  89. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
  90. 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
  91. 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  92. 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
  93. 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
  94. 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  95. };
  96. static uint8_t conv_ascii2bin(uint8_t a) {
  97. if (a >= 128) {
  98. return 0xFF;
  99. }
  100. return data_ascii2bin[a];
  101. }
  102. void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) {
  103. ctx->length = 48;
  104. ctx->num = 0;
  105. ctx->line_num = 0;
  106. }
  107. void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
  108. const uint8_t *in, size_t in_len) {
  109. unsigned i, j;
  110. unsigned total = 0;
  111. *out_len = 0;
  112. if (in_len == 0) {
  113. return;
  114. }
  115. assert(ctx->length <= sizeof(ctx->enc_data));
  116. if (ctx->num + in_len < ctx->length) {
  117. memcpy(&ctx->enc_data[ctx->num], in, in_len);
  118. ctx->num += in_len;
  119. return;
  120. }
  121. if (ctx->num != 0) {
  122. i = ctx->length - ctx->num;
  123. memcpy(&ctx->enc_data[ctx->num], in, i);
  124. in += i;
  125. in_len -= i;
  126. j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
  127. ctx->num = 0;
  128. out += j;
  129. *(out++) = '\n';
  130. *out = '\0';
  131. total = j + 1;
  132. }
  133. while (in_len >= ctx->length) {
  134. j = EVP_EncodeBlock(out, in, ctx->length);
  135. in += ctx->length;
  136. in_len -= ctx->length;
  137. out += j;
  138. *(out++) = '\n';
  139. *out = '\0';
  140. total += j + 1;
  141. }
  142. if (in_len != 0) {
  143. memcpy(&ctx->enc_data[0], in, in_len);
  144. }
  145. ctx->num = in_len;
  146. *out_len = total;
  147. }
  148. void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) {
  149. unsigned ret = 0;
  150. if (ctx->num != 0) {
  151. ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
  152. out[ret++] = '\n';
  153. out[ret] = '\0';
  154. ctx->num = 0;
  155. }
  156. *out_len = ret;
  157. }
  158. size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
  159. uint32_t l;
  160. size_t remaining = src_len, ret = 0;
  161. while (remaining) {
  162. if (remaining >= 3) {
  163. l = (((uint32_t)src[0]) << 16L) | (((uint32_t)src[1]) << 8L) | src[2];
  164. *(dst++) = conv_bin2ascii(l >> 18L);
  165. *(dst++) = conv_bin2ascii(l >> 12L);
  166. *(dst++) = conv_bin2ascii(l >> 6L);
  167. *(dst++) = conv_bin2ascii(l);
  168. remaining -= 3;
  169. } else {
  170. l = ((uint32_t)src[0]) << 16L;
  171. if (remaining == 2) {
  172. l |= ((uint32_t)src[1] << 8L);
  173. }
  174. *(dst++) = conv_bin2ascii(l >> 18L);
  175. *(dst++) = conv_bin2ascii(l >> 12L);
  176. *(dst++) = (remaining == 1) ? '=' : conv_bin2ascii(l >> 6L);
  177. *(dst++) = '=';
  178. remaining = 0;
  179. }
  180. ret += 4;
  181. src += 3;
  182. }
  183. *dst = '\0';
  184. return ret;
  185. }
  186. int EVP_DecodedLength(size_t *out_len, size_t len) {
  187. if (len % 4 != 0) {
  188. return 0;
  189. }
  190. *out_len = (len / 4) * 3;
  191. return 1;
  192. }
  193. int EVP_DecodeBase64(uint8_t *out, size_t *out_len, size_t max_out,
  194. const uint8_t *in, size_t in_len) {
  195. uint8_t a, b, c, d;
  196. size_t pad_len = 0, len = 0, max_len, i;
  197. uint32_t l;
  198. if (!EVP_DecodedLength(&max_len, in_len) || max_out < max_len) {
  199. return 0;
  200. }
  201. for (i = 0; i < in_len; i += 4) {
  202. a = conv_ascii2bin(*(in++));
  203. b = conv_ascii2bin(*(in++));
  204. if (i + 4 == in_len && in[1] == '=') {
  205. if (in[0] == '=') {
  206. pad_len = 2;
  207. } else {
  208. pad_len = 1;
  209. }
  210. }
  211. if (pad_len < 2) {
  212. c = conv_ascii2bin(*(in++));
  213. } else {
  214. c = 0;
  215. }
  216. if (pad_len < 1) {
  217. d = conv_ascii2bin(*(in++));
  218. } else {
  219. d = 0;
  220. }
  221. if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80)) {
  222. return 0;
  223. }
  224. l = ((((uint32_t)a) << 18L) | (((uint32_t)b) << 12L) |
  225. (((uint32_t)c) << 6L) | (((uint32_t)d)));
  226. *(out++) = (uint8_t)(l >> 16L) & 0xff;
  227. if (pad_len < 2) {
  228. *(out++) = (uint8_t)(l >> 8L) & 0xff;
  229. }
  230. if (pad_len < 1) {
  231. *(out++) = (uint8_t)(l) & 0xff;
  232. }
  233. len += 3 - pad_len;
  234. }
  235. *out_len = len;
  236. return 1;
  237. }
  238. void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) {
  239. ctx->length = 30;
  240. ctx->num = 0;
  241. ctx->line_num = 0;
  242. ctx->expect_nl = 0;
  243. }
  244. int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
  245. const uint8_t *in, size_t in_len) {
  246. int seof = -1, eof = 0, rv = -1, v, tmp, exp_nl;
  247. uint8_t *d;
  248. unsigned i, n, ln, ret = 0;
  249. n = ctx->num;
  250. d = ctx->enc_data;
  251. ln = ctx->line_num;
  252. exp_nl = ctx->expect_nl;
  253. /* last line of input. */
  254. if (in_len == 0 || (n == 0 && conv_ascii2bin(in[0]) == B64_EOF)) {
  255. rv = 0;
  256. goto end;
  257. }
  258. /* We parse the input data */
  259. for (i = 0; i < in_len; i++) {
  260. /* If the current line is > 80 characters, scream alot */
  261. if (ln >= 80) {
  262. rv = -1;
  263. goto end;
  264. }
  265. /* Get char and put it into the buffer */
  266. tmp = *(in++);
  267. v = conv_ascii2bin(tmp);
  268. /* only save the good data :-) */
  269. if (!B64_NOT_BASE64(v)) {
  270. assert(n < sizeof(ctx->enc_data));
  271. d[n++] = tmp;
  272. ln++;
  273. } else if (v == B64_ERROR) {
  274. rv = -1;
  275. goto end;
  276. }
  277. /* have we seen a '=' which is 'definitly' the last
  278. * input line. seof will point to the character that
  279. * holds it. and eof will hold how many characters to
  280. * chop off. */
  281. if (tmp == '=') {
  282. if (seof == -1) {
  283. seof = n;
  284. }
  285. eof++;
  286. if (eof > 2) {
  287. /* There are, at most, two equals signs at the end of base64 data. */
  288. rv = -1;
  289. goto end;
  290. }
  291. }
  292. if (v == B64_CR) {
  293. ln = 0;
  294. if (exp_nl) {
  295. continue;
  296. }
  297. }
  298. /* eoln */
  299. if (v == B64_EOLN) {
  300. ln = 0;
  301. if (exp_nl) {
  302. exp_nl = 0;
  303. continue;
  304. }
  305. }
  306. exp_nl = 0;
  307. /* If we are at the end of input and it looks like a
  308. * line, process it. */
  309. if ((i + 1) == in_len && (((n & 3) == 0) || eof)) {
  310. v = B64_EOF;
  311. /* In case things were given us in really small
  312. records (so two '=' were given in separate
  313. updates), eof may contain the incorrect number
  314. of ending bytes to skip, so let's redo the count */
  315. eof = 0;
  316. if (d[n - 1] == '=') {
  317. eof++;
  318. }
  319. if (d[n - 2] == '=') {
  320. eof++;
  321. }
  322. /* There will never be more than two '=' */
  323. }
  324. if ((v == B64_EOF && (n & 3) == 0) || n >= 64) {
  325. /* This is needed to work correctly on 64 byte input
  326. * lines. We process the line and then need to
  327. * accept the '\n' */
  328. if (v != B64_EOF && n >= 64) {
  329. exp_nl = 1;
  330. }
  331. if (n > 0) {
  332. /* TODO(davidben): Switch this to EVP_DecodeBase64. */
  333. v = EVP_DecodeBlock(out, d, n);
  334. n = 0;
  335. if (v < 0) {
  336. rv = 0;
  337. goto end;
  338. }
  339. ret += (v - eof);
  340. } else {
  341. eof = 1;
  342. v = 0;
  343. }
  344. /* This is the case where we have had a short
  345. * but valid input line */
  346. if (v < (int)ctx->length && eof) {
  347. rv = 0;
  348. goto end;
  349. } else {
  350. ctx->length = v;
  351. }
  352. if (seof >= 0) {
  353. rv = 0;
  354. goto end;
  355. }
  356. out += v;
  357. }
  358. }
  359. rv = 1;
  360. end:
  361. *out_len = ret;
  362. ctx->num = n;
  363. ctx->line_num = ln;
  364. ctx->expect_nl = exp_nl;
  365. return rv;
  366. }
  367. int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *outl) {
  368. int i;
  369. *outl = 0;
  370. if (ctx->num != 0) {
  371. /* TODO(davidben): Switch this to EVP_DecodeBase64. */
  372. i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num);
  373. if (i < 0) {
  374. return -1;
  375. }
  376. ctx->num = 0;
  377. *outl = i;
  378. return 1;
  379. } else {
  380. return 1;
  381. }
  382. }
  383. int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
  384. size_t dst_len;
  385. /* trim white space from the start of the line. */
  386. while (conv_ascii2bin(*src) == B64_WS && src_len > 0) {
  387. src++;
  388. src_len--;
  389. }
  390. /* strip off stuff at the end of the line
  391. * ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */
  392. while (src_len > 3 && B64_NOT_BASE64(conv_ascii2bin(src[src_len - 1]))) {
  393. src_len--;
  394. }
  395. if (!EVP_DecodedLength(&dst_len, src_len) || dst_len > INT_MAX) {
  396. return -1;
  397. }
  398. if (!EVP_DecodeBase64(dst, &dst_len, dst_len, src, src_len)) {
  399. return -1;
  400. }
  401. /* EVP_DecodeBlock does not take padding into account, so put the
  402. * NULs back in... so the caller can strip them back out. */
  403. while (dst_len % 3 != 0) {
  404. dst[dst_len++] = '\0';
  405. }
  406. assert(dst_len <= INT_MAX);
  407. return dst_len;
  408. }
  409. int EVP_EncodedLength(size_t *out_len, size_t len) {
  410. if (len + 2 < len) {
  411. return 0;
  412. }
  413. len += 2;
  414. len /= 3;
  415. if (((len << 2) >> 2) != len) {
  416. return 0;
  417. }
  418. len <<= 2;
  419. if (len + 1 < len) {
  420. return 0;
  421. }
  422. len++;
  423. *out_len = len;
  424. return 1;
  425. }