fp64 of public ID: include the public key in it!
[xonotic/d0_blind_id.git] / d0_iobuf.c
1 /*
2 Blind-ID library for user identification using RSA blind signatures
3 Copyright (C) 2010  Rudolf Polzer
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19
20 #include "d0_iobuf.h"
21
22 #include <string.h>
23
24 struct d0_iobuf_s
25 {
26         const unsigned char *inbuf;
27         unsigned char *outbuf;
28         size_t inpos, outpos, inbuflen, outbuflen;
29         BOOL ok;
30 };
31
32 d0_iobuf_t *d0_iobuf_open_read(const void *buf, size_t len)
33 {
34         d0_iobuf_t *b = d0_malloc(sizeof(d0_iobuf_t));
35         b->inbuf = (const unsigned char *) buf;
36         b->outbuf = NULL;
37         b->inpos = b->outpos = 0;
38         b->inbuflen = len;
39         b->outbuflen = 0;
40         b->ok = 1;
41         return b;
42 }
43
44 d0_iobuf_t *d0_iobuf_open_write(void *buf, size_t len)
45 {
46         d0_iobuf_t *b = d0_malloc(sizeof(d0_iobuf_t));
47         b->inbuf = (const unsigned char *) buf;
48         b->outbuf = (unsigned char *) buf;
49         b->inpos = b->outpos = 0;
50         b->inbuflen = len;
51         b->outbuflen = len;
52         b->ok = 1;
53         return b;
54 }
55
56 BOOL d0_iobuf_close(d0_iobuf_t *buf, size_t *len)
57 {
58         BOOL r = buf->ok;
59         if(len)
60                 *len = buf->outpos;
61         d0_free(buf);
62         return r;
63 }
64
65 size_t d0_iobuf_write_raw(d0_iobuf_t *buf, const void *s, size_t n)
66 {
67         size_t nreal = n;
68         if(nreal > buf->outbuflen - buf->outpos)
69         {
70                 buf->ok = 0;
71                 nreal = buf->outbuflen - buf->outpos;
72         }
73         memcpy(buf->outbuf + buf->outpos, s, nreal);
74         buf->outpos += nreal;
75         return nreal;
76 }
77
78 size_t d0_iobuf_read_raw(d0_iobuf_t *buf, void *s, size_t n)
79 {
80         size_t nreal = n;
81         if(nreal > buf->inbuflen - buf->inpos)
82         {
83                 buf->ok = 0;
84                 nreal = buf->inbuflen - buf->inpos;
85         }
86         memcpy(s, buf->inbuf + buf->inpos, nreal);
87         buf->inpos += nreal;
88         return nreal;
89 }
90
91 BOOL d0_iobuf_write_packet(d0_iobuf_t *buf, const void *s, size_t n)
92 {
93         unsigned char c;
94         size_t nn = n;
95         while(nn)
96         {
97                 c = nn & 0x7F;
98                 nn >>= 7;
99                 if(nn)
100                         c |= 0x80;
101                 if(d0_iobuf_write_raw(buf, &c, 1) != 1)
102                         return 0;
103         }
104         if(d0_iobuf_write_raw(buf, s, n) != n)
105                 return 0;
106         return 1;
107 }
108
109 BOOL d0_iobuf_read_packet(d0_iobuf_t *buf, void *s, size_t *np)
110 {
111         unsigned char c;
112         size_t n = 0;
113         size_t nn = 1;
114         do
115         {
116                 if(d0_iobuf_read_raw(buf, &c, 1) != 1)
117                         return 0;
118                 n |= nn * (c & 0x7F);
119                 nn <<= 7;
120         }
121         while(c & 0x80);
122         if(n > *np)
123                 return 0;
124         if(d0_iobuf_read_raw(buf, s, n) != n)
125                 return 0;
126         *np = n;
127         return 1;
128 }
129
130 BOOL d0_iobuf_conv_base64_in(d0_iobuf_t *buf)
131 {
132         // compand the in-buffer
133         return 0;
134 }
135
136 static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
137 static void base64_3to4(const unsigned char *in, unsigned char *out, int bytes)
138 {
139         unsigned char i0 = (bytes > 0) ? in[0] : 0;
140         unsigned char i1 = (bytes > 1) ? in[1] : 0;
141         unsigned char i2 = (bytes > 2) ? in[2] : 0;
142         unsigned char o0 = base64[i0 >> 2];
143         unsigned char o1 = base64[((i0 << 4) | (i1 >> 4)) & 077];
144         unsigned char o2 = base64[((i1 << 2) | (i2 >> 6)) & 077];
145         unsigned char o3 = base64[i2 & 077];
146         out[0] = (bytes > 0) ? o0 : '?';
147         out[1] = (bytes > 0) ? o1 : '?';
148         out[2] = (bytes > 1) ? o2 : '=';
149         out[3] = (bytes > 2) ? o3 : '=';
150 }
151
152 BOOL d0_iobuf_conv_base64_out(d0_iobuf_t *buf)
153 {
154         size_t blocks, i;
155         // expand the out-buffer
156         blocks = ((buf->outpos + 2) / 3);
157         if(blocks*4 > buf->outbuflen)
158                 return 0;
159         for(i = blocks; i > 0; )
160         {
161                 --i;
162                 base64_3to4(buf->outbuf + 3*i, buf->outbuf + 4*i, buf->outpos - 3*i);
163         }
164         buf->outpos = blocks * 4;
165         return 1;
166 }