No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 
 
 

479 líneas
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. #include <string.h>
  60. static const unsigned char data_bin2ascii[65] =
  61. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  62. #define conv_bin2ascii(a) (data_bin2ascii[(a) & 0x3f])
  63. /* 64 char lines
  64. * pad input with 0
  65. * left over chars are set to =
  66. * 1 byte => xx==
  67. * 2 bytes => xxx=
  68. * 3 bytes => xxxx
  69. */
  70. #define BIN_PER_LINE (64/4*3)
  71. #define CHUNKS_PER_LINE (64/4)
  72. #define CHAR_PER_LINE (64+1)
  73. /* 0xF0 is a EOLN
  74. * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
  75. * 0xF2 is EOF
  76. * 0xE0 is ignore at start of line.
  77. * 0xFF is error */
  78. #define B64_EOLN 0xF0
  79. #define B64_CR 0xF1
  80. #define B64_EOF 0xF2
  81. #define B64_WS 0xE0
  82. #define B64_ERROR 0xFF
  83. #define B64_NOT_BASE64(a) (((a) | 0x13) == 0xF3)
  84. static const uint8_t data_ascii2bin[128] = {
  85. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xF0, 0xFF,
  86. 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  87. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF,
  88. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
  89. 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
  90. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
  91. 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
  92. 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  93. 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
  94. 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
  95. 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  96. };
  97. static uint8_t conv_ascii2bin(uint8_t a) {
  98. if (a >= 128) {
  99. return 0xFF;
  100. }
  101. return data_ascii2bin[a];
  102. }
  103. void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) {
  104. ctx->length = 48;
  105. ctx->num = 0;
  106. ctx->line_num = 0;
  107. }
  108. void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
  109. const uint8_t *in, size_t in_len) {
  110. unsigned i, j;
  111. unsigned total = 0;
  112. *out_len = 0;
  113. if (in_len == 0) {
  114. return;
  115. }
  116. assert(ctx->length <= sizeof(ctx->enc_data));
  117. if (ctx->num + in_len < ctx->length) {
  118. memcpy(&ctx->enc_data[ctx->num], in, in_len);
  119. ctx->num += in_len;
  120. return;
  121. }
  122. if (ctx->num != 0) {
  123. i = ctx->length - ctx->num;
  124. memcpy(&ctx->enc_data[ctx->num], in, i);
  125. in += i;
  126. in_len -= i;
  127. j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
  128. ctx->num = 0;
  129. out += j;
  130. *(out++) = '\n';
  131. *out = '\0';
  132. total = j + 1;
  133. }
  134. while (in_len >= ctx->length) {
  135. j = EVP_EncodeBlock(out, in, ctx->length);
  136. in += ctx->length;
  137. in_len -= ctx->length;
  138. out += j;
  139. *(out++) = '\n';
  140. *out = '\0';
  141. total += j + 1;
  142. }
  143. if (in_len != 0) {
  144. memcpy(&ctx->enc_data[0], in, in_len);
  145. }
  146. ctx->num = in_len;
  147. *out_len = total;
  148. }
  149. void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) {
  150. unsigned ret = 0;
  151. if (ctx->num != 0) {
  152. ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
  153. out[ret++] = '\n';
  154. out[ret] = '\0';
  155. ctx->num = 0;
  156. }
  157. *out_len = ret;
  158. }
  159. size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
  160. uint32_t l;
  161. size_t remaining = src_len, ret = 0;
  162. while (remaining) {
  163. if (remaining >= 3) {
  164. l = (((uint32_t)src[0]) << 16L) | (((uint32_t)src[1]) << 8L) | src[2];
  165. *(dst++) = conv_bin2ascii(l >> 18L);
  166. *(dst++) = conv_bin2ascii(l >> 12L);
  167. *(dst++) = conv_bin2ascii(l >> 6L);
  168. *(dst++) = conv_bin2ascii(l);
  169. remaining -= 3;
  170. } else {
  171. l = ((uint32_t)src[0]) << 16L;
  172. if (remaining == 2) {
  173. l |= ((uint32_t)src[1] << 8L);
  174. }
  175. *(dst++) = conv_bin2ascii(l >> 18L);
  176. *(dst++) = conv_bin2ascii(l >> 12L);
  177. *(dst++) = (remaining == 1) ? '=' : conv_bin2ascii(l >> 6L);
  178. *(dst++) = '=';
  179. remaining = 0;
  180. }
  181. ret += 4;
  182. src += 3;
  183. }
  184. *dst = '\0';
  185. return ret;
  186. }
  187. int EVP_DecodedLength(size_t *out_len, size_t len) {
  188. if (len % 4 != 0) {
  189. return 0;
  190. }
  191. *out_len = (len / 4) * 3;
  192. return 1;
  193. }
  194. int EVP_DecodeBase64(uint8_t *out, size_t *out_len, size_t max_out,
  195. const uint8_t *in, size_t in_len) {
  196. uint8_t a, b, c, d;
  197. size_t pad_len = 0, len = 0, max_len, i;
  198. uint32_t l;
  199. if (!EVP_DecodedLength(&max_len, in_len) || max_out < max_len) {
  200. return 0;
  201. }
  202. for (i = 0; i < in_len; i += 4) {
  203. a = conv_ascii2bin(*(in++));
  204. b = conv_ascii2bin(*(in++));
  205. if (i + 4 == in_len && in[1] == '=') {
  206. if (in[0] == '=') {
  207. pad_len = 2;
  208. } else {
  209. pad_len = 1;
  210. }
  211. }
  212. if (pad_len < 2) {
  213. c = conv_ascii2bin(*(in++));
  214. } else {
  215. c = 0;
  216. }
  217. if (pad_len < 1) {
  218. d = conv_ascii2bin(*(in++));
  219. } else {
  220. d = 0;
  221. }
  222. if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80)) {
  223. return 0;
  224. }
  225. l = ((((uint32_t)a) << 18L) | (((uint32_t)b) << 12L) |
  226. (((uint32_t)c) << 6L) | (((uint32_t)d)));
  227. *(out++) = (uint8_t)(l >> 16L) & 0xff;
  228. if (pad_len < 2) {
  229. *(out++) = (uint8_t)(l >> 8L) & 0xff;
  230. }
  231. if (pad_len < 1) {
  232. *(out++) = (uint8_t)(l) & 0xff;
  233. }
  234. len += 3 - pad_len;
  235. }
  236. *out_len = len;
  237. return 1;
  238. }
  239. void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) {
  240. ctx->length = 30;
  241. ctx->num = 0;
  242. ctx->line_num = 0;
  243. ctx->expect_nl = 0;
  244. }
  245. int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
  246. const uint8_t *in, size_t in_len) {
  247. int seof = -1, eof = 0, rv = -1, v, tmp, exp_nl;
  248. uint8_t *d;
  249. unsigned i, n, ln, ret = 0;
  250. n = ctx->num;
  251. d = ctx->enc_data;
  252. ln = ctx->line_num;
  253. exp_nl = ctx->expect_nl;
  254. /* last line of input. */
  255. if (in_len == 0 || (n == 0 && conv_ascii2bin(in[0]) == B64_EOF)) {
  256. rv = 0;
  257. goto end;
  258. }
  259. /* We parse the input data */
  260. for (i = 0; i < in_len; i++) {
  261. /* If the current line is > 80 characters, scream alot */
  262. if (ln >= 80) {
  263. rv = -1;
  264. goto end;
  265. }
  266. /* Get char and put it into the buffer */
  267. tmp = *(in++);
  268. v = conv_ascii2bin(tmp);
  269. /* only save the good data :-) */
  270. if (!B64_NOT_BASE64(v)) {
  271. assert(n < sizeof(ctx->enc_data));
  272. d[n++] = tmp;
  273. ln++;
  274. } else if (v == B64_ERROR) {
  275. rv = -1;
  276. goto end;
  277. }
  278. /* have we seen a '=' which is 'definitly' the last
  279. * input line. seof will point to the character that
  280. * holds it. and eof will hold how many characters to
  281. * chop off. */
  282. if (tmp == '=') {
  283. if (seof == -1) {
  284. seof = n;
  285. }
  286. eof++;
  287. if (eof > 2) {
  288. /* There are, at most, two equals signs at the end of base64 data. */
  289. rv = -1;
  290. goto end;
  291. }
  292. }
  293. if (v == B64_CR) {
  294. ln = 0;
  295. if (exp_nl) {
  296. continue;
  297. }
  298. }
  299. /* eoln */
  300. if (v == B64_EOLN) {
  301. ln = 0;
  302. if (exp_nl) {
  303. exp_nl = 0;
  304. continue;
  305. }
  306. }
  307. exp_nl = 0;
  308. /* If we are at the end of input and it looks like a
  309. * line, process it. */
  310. if ((i + 1) == in_len && (((n & 3) == 0) || eof)) {
  311. v = B64_EOF;
  312. /* In case things were given us in really small
  313. records (so two '=' were given in separate
  314. updates), eof may contain the incorrect number
  315. of ending bytes to skip, so let's redo the count */
  316. eof = 0;
  317. if (d[n - 1] == '=') {
  318. eof++;
  319. }
  320. if (d[n - 2] == '=') {
  321. eof++;
  322. }
  323. /* There will never be more than two '=' */
  324. }
  325. if ((v == B64_EOF && (n & 3) == 0) || n >= 64) {
  326. /* This is needed to work correctly on 64 byte input
  327. * lines. We process the line and then need to
  328. * accept the '\n' */
  329. if (v != B64_EOF && n >= 64) {
  330. exp_nl = 1;
  331. }
  332. if (n > 0) {
  333. /* TODO(davidben): Switch this to EVP_DecodeBase64. */
  334. v = EVP_DecodeBlock(out, d, n);
  335. n = 0;
  336. if (v < 0) {
  337. rv = 0;
  338. goto end;
  339. }
  340. if (eof > v) {
  341. rv = -1;
  342. goto end;
  343. }
  344. ret += (v - eof);
  345. } else {
  346. eof = 1;
  347. v = 0;
  348. }
  349. /* This is the case where we have had a short
  350. * but valid input line */
  351. if (v < (int)ctx->length && eof) {
  352. rv = 0;
  353. goto end;
  354. } else {
  355. ctx->length = v;
  356. }
  357. if (seof >= 0) {
  358. rv = 0;
  359. goto end;
  360. }
  361. out += v;
  362. }
  363. }
  364. rv = 1;
  365. end:
  366. *out_len = ret;
  367. ctx->num = n;
  368. ctx->line_num = ln;
  369. ctx->expect_nl = exp_nl;
  370. return rv;
  371. }
  372. int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *outl) {
  373. int i;
  374. *outl = 0;
  375. if (ctx->num != 0) {
  376. /* TODO(davidben): Switch this to EVP_DecodeBase64. */
  377. i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num);
  378. if (i < 0) {
  379. return -1;
  380. }
  381. ctx->num = 0;
  382. *outl = i;
  383. return 1;
  384. } else {
  385. return 1;
  386. }
  387. }
  388. int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
  389. size_t dst_len;
  390. /* trim white space from the start of the line. */
  391. while (conv_ascii2bin(*src) == B64_WS && src_len > 0) {
  392. src++;
  393. src_len--;
  394. }
  395. /* strip off stuff at the end of the line
  396. * ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */
  397. while (src_len > 3 && B64_NOT_BASE64(conv_ascii2bin(src[src_len - 1]))) {
  398. src_len--;
  399. }
  400. if (!EVP_DecodedLength(&dst_len, src_len) || dst_len > INT_MAX) {
  401. return -1;
  402. }
  403. if (!EVP_DecodeBase64(dst, &dst_len, dst_len, src, src_len)) {
  404. return -1;
  405. }
  406. /* EVP_DecodeBlock does not take padding into account, so put the
  407. * NULs back in... so the caller can strip them back out. */
  408. while (dst_len % 3 != 0) {
  409. dst[dst_len++] = '\0';
  410. }
  411. assert(dst_len <= INT_MAX);
  412. return dst_len;
  413. }
  414. int EVP_EncodedLength(size_t *out_len, size_t len) {
  415. if (len + 2 < len) {
  416. return 0;
  417. }
  418. len += 2;
  419. len /= 3;
  420. if (((len << 2) >> 2) != len) {
  421. return 0;
  422. }
  423. len <<= 2;
  424. if (len + 1 < len) {
  425. return 0;
  426. }
  427. len++;
  428. *out_len = len;
  429. return 1;
  430. }