~ubuntu-branches/ubuntu/trusty/libesmtp/trusty-proposed

« back to all changes in this revision

Viewing changes to base64.c

  • Committer: Bazaar Package Importer
  • Author(s): Jeremy T. Bouse
  • Date: 2002-03-06 08:37:48 UTC
  • Revision ID: james.westby@ubuntu.com-20020306083748-ihmt32mddsslvg5i
Tags: upstream-0.8.11
ImportĀ upstreamĀ versionĀ 0.8.11

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  This file is part of libESMTP, a library for submission of RFC 2822
 
3
 *  formatted electronic mail messages using the SMTP protocol described
 
4
 *  in RFC 2821.
 
5
 *
 
6
 *  Copyright (C) 2001,2002  Brian Stafford  <brian@stafford.uklinux.net>
 
7
 *
 
8
 *  This library is free software; you can redistribute it and/or
 
9
 *  modify it under the terms of the GNU Lesser General Public
 
10
 *  License as published by the Free Software Foundation; either
 
11
 *  version 2.1 of the License, or (at your option) any later version.
 
12
 *
 
13
 *  This library is distributed in the hope that it will be useful,
 
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
 *  Lesser General Public License for more details.
 
17
 *
 
18
 *  You should have received a copy of the GNU Lesser General Public
 
19
 *  License along with this library; if not, write to the Free Software
 
20
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
21
 */
 
22
 
 
23
#ifdef HAVE_CONFIG_H
 
24
#include <config.h>
 
25
#endif
 
26
 
 
27
#include <assert.h>
 
28
 
 
29
/* Routines to encode and decode base64 text.
 
30
 */
 
31
#include <ctype.h>
 
32
#include <string.h>
 
33
#include "base64.h"
 
34
 
 
35
/* RFC 2045 section 6.8 */
 
36
 
 
37
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
38
                             "abcdefghijklmnopqrstuvwxyz"
 
39
                             "0123456789"
 
40
                             "+/";
 
41
 
 
42
static const char index_64[128] =
 
43
  {
 
44
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 
45
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 
46
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
 
47
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
 
48
    -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
 
49
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
 
50
    -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
 
51
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
 
52
  };
 
53
 
 
54
/* Decode srclen bytes of base64 data contained in src and put the result
 
55
   in dst.  Since the destination buffer may contain arbitrary binary
 
56
   data and it is not necessarily a string, there is no \0 byte at the
 
57
   end of the decoded data. */
 
58
int
 
59
b64_decode (void *dst, int dstlen, const char *src, int srclen)
 
60
{
 
61
  const unsigned char *p, *q;
 
62
  unsigned char *t;
 
63
  int c1, c2;
 
64
 
 
65
  assert (dst != NULL && dstlen > 0 && src != NULL);
 
66
 
 
67
  if (srclen < 0)
 
68
    srclen = strlen (src);
 
69
 
 
70
  /* Remove leading and trailing white space */
 
71
  for (p = (const unsigned char *) src;
 
72
       srclen > 0 && isspace (*p);
 
73
       p++, srclen--)
 
74
    ;
 
75
  for (q = p + srclen - 1; q >= p && isspace (*q); q--, srclen--)
 
76
    ;
 
77
 
 
78
  /* Length MUST be a multiple of 4 */
 
79
  if (srclen % 4 != 0)
 
80
    return -1;
 
81
 
 
82
  /* Destination buffer length must be sufficient */
 
83
  if (srclen / 4 * 3 + 1 > dstlen)
 
84
    return -1;
 
85
 
 
86
  t = dst;
 
87
  while (srclen > 0)
 
88
    {
 
89
      srclen -= 4;
 
90
      if (*p >= 128 || (c1 = index_64[*p++]) == -1)
 
91
        return -1;
 
92
      if (*p >= 128 || (c2 = index_64[*p++]) == -1)
 
93
        return -1;
 
94
      *t++ = (c1 << 2) | ((c2 & 0x30) >> 4);
 
95
 
 
96
      if (p[0] == '=' && p[1] == '=')
 
97
        break;
 
98
      if (*p >= 128 || (c1 = index_64[*p++]) == -1)
 
99
        return -1;
 
100
      *t++ = ((c2 & 0x0f) << 4) | ((c1 & 0x3c) >> 2);
 
101
 
 
102
      if (p[0] == '=')
 
103
        break;
 
104
      if (*p >= 128 || (c2 = index_64[*p++]) == -1)
 
105
        return -1;
 
106
      *t++ = ((c1 & 0x03) << 6) | c2;
 
107
    }
 
108
 
 
109
  return t - (unsigned char *) dst;
 
110
}
 
111
 
 
112
/* Return a pointer to a base 64 encoded string.  The input data is
 
113
   arbitrary binary data, the output is a \0 terminated string.
 
114
   src and dst may not share the same buffer.  */
 
115
int
 
116
b64_encode (char *dst, int dstlen, const void *src, int srclen)
 
117
{
 
118
  char *to = dst;
 
119
  const unsigned char *from;
 
120
  unsigned char c1, c2;
 
121
  int dst_needed;
 
122
 
 
123
  assert (dst != NULL && dstlen > 0 && src != NULL && srclen >= 0);
 
124
 
 
125
  dst_needed = (srclen + 2) / 3;
 
126
  dst_needed *= 4;
 
127
  if (dstlen < dst_needed + 1)
 
128
    return -1;
 
129
 
 
130
  from = src;
 
131
  while (srclen > 0)
 
132
    {
 
133
      c1 = *from++; srclen--;
 
134
      *to++ = base64[c1 >> 2];
 
135
      c1 = (c1 & 0x03) << 4;
 
136
      if (srclen <= 0)
 
137
        {
 
138
          *to++ = base64[c1];
 
139
          *to++ = '=';
 
140
          *to++ = '=';
 
141
          break;
 
142
        }
 
143
      c2 = *from++; srclen--;
 
144
      c1 |= (c2 >> 4) & 0x0f;
 
145
      *to++ = base64[c1];
 
146
      c1 = (c2 & 0x0f) << 2;
 
147
      if (srclen <= 0)
 
148
        {
 
149
          *to++ = base64[c1];
 
150
          *to++ = '=';
 
151
          break;
 
152
        }
 
153
      c2 = *from++; srclen--;
 
154
      c1 |= (c2 >> 6) & 0x03;
 
155
      *to++ = base64[c1];
 
156
      *to++ = base64[c2 & 0x3f];
 
157
    }
 
158
  *to = '\0';
 
159
  return to - dst;
 
160
}
 
161