Merge branch 't/uptime_cleanup'
[paraslash.git] / crypt_common.c
1 /*
2  * Copyright (C) 2005-2011 Andre Noll <maan@systemlinux.org>
3  *
4  * Licensed under the GPL v2. For licencing details see COPYING.
5  */
6
7 /** \file crypt_common.c Crypto functions independent of openssl/libgcrypt. */
8
9 #include <regex.h>
10 #include <stdbool.h>
11
12 #include "para.h"
13 #include "error.h"
14 #include "string.h"
15 #include "crypt_backend.h"
16 #include "crypt.h"
17
18 /** If the key begins with this text, we treat it as an ssh key. */
19 #define KEY_TYPE_TXT "ssh-rsa"
20
21 /**
22  * Check if given buffer starts with a ssh rsa key signature.
23  *
24  * \param data The buffer.
25  * \param size Number of data bytes.
26  *
27  * \return Number of header bytes to be skipped on success, zero if
28  * ssh rsa signature was not found.
29  */
30 size_t is_ssh_rsa_key(char *data, size_t size)
31 {
32         char *cp;
33
34         if (size < strlen(KEY_TYPE_TXT) + 2)
35                 return 0;
36         cp = memchr(data, ' ', size);
37         if (cp == NULL)
38                 return 0;
39         if (strncmp(KEY_TYPE_TXT, data, strlen(KEY_TYPE_TXT)))
40                 return 0;
41         cp++;
42         if (cp >= data + size)
43                 return 0;
44         if (*cp == '\0')
45                 return 0;
46         return cp - data;
47 }
48
49 /*
50  * This base64/uudecode stuff below is taken from openssh-5.2p1, Copyright (c)
51  * 1996 by Internet Software Consortium.  Portions Copyright (c) 1995 by
52  * International Business Machines, Inc.
53  */
54
55 static const char Base64[] =
56         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
57 static const char Pad64 = '=';
58
59 /**
60  * base64-decode a buffer.
61  *
62  * \param src The buffer to decode.
63  * \param target Result is stored here.
64  * \param targsize Number of bytes of \a target.
65  *
66  * Skips all whitespace anywhere. Converts characters, four at a time, starting
67  * at (or after) src from base - 64 numbers into three 8 bit bytes in the
68  * target area.
69  *
70  * \return The number of data bytes stored at the target, -E_BASE64 on errors.
71  */
72 int base64_decode(char const *src, unsigned char *target, size_t targsize)
73 {
74         unsigned int tarindex, state;
75         int ch;
76         char *pos;
77
78         state = 0;
79         tarindex = 0;
80
81         while ((ch = *src++) != '\0') {
82                 if (para_isspace(ch)) /* Skip whitespace anywhere. */
83                         continue;
84
85                 if (ch == Pad64)
86                         break;
87
88                 pos = strchr(Base64, ch);
89                 if (pos == NULL) /* A non-base64 character. */
90                         return -E_BASE64;
91
92                 switch (state) {
93                 case 0:
94                         if (target) {
95                                 if (tarindex >= targsize)
96                                         return -E_BASE64;
97                                 target[tarindex] = (pos - Base64) << 2;
98                         }
99                         state = 1;
100                         break;
101                 case 1:
102                         if (target) {
103                                 if (tarindex + 1 >= targsize)
104                                         return -E_BASE64;
105                                 target[tarindex]   |=  (pos - Base64) >> 4;
106                                 target[tarindex+1]  = ((pos - Base64) & 0x0f)
107                                                         << 4 ;
108                         }
109                         tarindex++;
110                         state = 2;
111                         break;
112                 case 2:
113                         if (target) {
114                                 if (tarindex + 1 >= targsize)
115                                         return -E_BASE64;
116                                 target[tarindex]   |=  (pos - Base64) >> 2;
117                                 target[tarindex+1]  = ((pos - Base64) & 0x03)
118                                                         << 6;
119                         }
120                         tarindex++;
121                         state = 3;
122                         break;
123                 case 3:
124                         if (target) {
125                                 if (tarindex >= targsize)
126                                         return -E_BASE64;
127                                 target[tarindex] |= (pos - Base64);
128                         }
129                         tarindex++;
130                         state = 0;
131                         break;
132                 }
133         }
134
135         /*
136          * We are done decoding Base-64 chars.  Let's see if we ended
137          * on a byte boundary, and/or with erroneous trailing characters.
138          */
139
140         if (ch == Pad64) {              /* We got a pad char. */
141                 ch = *src++;            /* Skip it, get next. */
142                 switch (state) {
143                 case 0:         /* Invalid = in first position */
144                 case 1:         /* Invalid = in second position */
145                         return -E_BASE64;
146
147                 case 2:         /* Valid, means one byte of info */
148                         /* Skip any number of spaces. */
149                         for (; ch != '\0'; ch = *src++)
150                                 if (!isspace(ch))
151                                         break;
152                         /* Make sure there is another trailing = sign. */
153                         if (ch != Pad64)
154                                 return -E_BASE64;
155                         ch = *src++;            /* Skip the = */
156                         /* Fall through to "single trailing =" case. */
157                         /* FALLTHROUGH */
158
159                 case 3:         /* Valid, means two bytes of info */
160                         /*
161                          * We know this char is an =.  Is there anything but
162                          * whitespace after it?
163                          */
164                         for (; ch != '\0'; ch = *src++)
165                                 if (!isspace(ch))
166                                         return -E_BASE64;
167
168                         /*
169                          * Now make sure for cases 2 and 3 that the "extra"
170                          * bits that slopped past the last full byte were
171                          * zeros.  If we don't check them, they become a
172                          * subliminal channel.
173                          */
174                         if (target && target[tarindex] != 0)
175                                 return -E_BASE64;
176                 }
177         } else {
178                 /*
179                  * We ended by seeing the end of the string.  Make sure we
180                  * have no partial bytes lying around.
181                  */
182                 if (state != 0)
183                         return -E_BASE64;
184         }
185
186         return tarindex;
187 }
188
189 /**
190  * uudecode a buffer.
191  *
192  * \param src The buffer to decode.
193  * \param target Result buffer.
194  * \param targsize The length of \a target in bytes.
195  *
196  * This is just a simple wrapper for base64_decode() which strips whitespace.
197  *
198  * \return The return value of the underlying call to base64_decode().
199  */
200 int uudecode(const char *src, unsigned char *target, size_t targsize)
201 {
202         int len;
203         char *encoded, *p;
204
205         /* copy the 'readonly' source */
206         encoded = para_strdup(src);
207         /* skip whitespace and data */
208         for (p = encoded; *p == ' ' || *p == '\t'; p++)
209                 ;
210         for (; *p != '\0' && *p != ' ' && *p != '\t'; p++)
211                 ;
212         /* and remove trailing whitespace because base64_decode needs this */
213         *p = '\0';
214         len = base64_decode(encoded, target, targsize);
215         free(encoded);
216         return len;
217 }
218
219 /**
220  * Read a 4-byte number from a buffer in big-endian format.
221  *
222  * \param vp The buffer.
223  *
224  * The byte-order of the buffer is expected to be big-endian, unlike read_u32()
225  * of portable_io.h which expects little endian.
226  *
227  * \return The 32 bit number given by \a vp.
228  */
229 uint32_t read_ssh_u32(const void *vp)
230 {
231         const unsigned char *p = (const unsigned char *)vp;
232         uint32_t v;
233
234         v  = (uint32_t)p[0] << 24;
235         v |= (uint32_t)p[1] << 16;
236         v |= (uint32_t)p[2] << 8;
237         v |= (uint32_t)p[3];
238
239         return v;
240 }
241
242 /**
243  * Sanity checks for the header of an ssh key.
244  *
245  * \param blob The buffer.
246  * \param blen The number of bytes of \a blob.
247  *
248  * This performs some checks to make sure we really have an ssh key. It also
249  * computes the offset in bytes of the start of the key values (modulus,
250  * exponent..).
251  *
252  * \return The number of bytes to skip until the start of the first encoded
253  * number (usually 11).
254  */
255 int check_ssh_key_header(const unsigned char *blob, int blen)
256 {
257         const unsigned char *p = blob, *end = blob + blen;
258         uint32_t rlen;
259
260         if (p + 4 > end)
261                 return -E_SSH_KEY_HEADER;
262         rlen = read_ssh_u32(p);
263         p += 4;
264         if (p + rlen < p)
265                 return -E_SSH_KEY_HEADER;
266         if (p + rlen > end)
267                 return -E_SSH_KEY_HEADER;
268         if (rlen < strlen(KEY_TYPE_TXT))
269                 return -E_SSH_KEY_HEADER;
270         PARA_DEBUG_LOG("type: %s, rlen: %d\n", p, rlen);
271         if (strncmp((char *)p, KEY_TYPE_TXT, strlen(KEY_TYPE_TXT)))
272                 return -E_SSH_KEY_HEADER;
273         return 4 + rlen;
274 }
275
276 /**
277  * Check existence and permissions of a key file.
278  *
279  * \param file The path of the key file.
280  * \param private_key Whether this is a private key.
281  *
282  * This checks whether the file exists. If it is a private key, we additionally
283  * check that the permissions are restrictive enough. It is considered an error
284  * if we own the file and it is readable for others.
285  *
286  * \return Standard.
287  */
288 int check_key_file(const char *file, bool private_key)
289 {
290         struct stat st;
291
292         if (stat(file, &st) != 0)
293                 return -ERRNO_TO_PARA_ERROR(errno);
294         if (!private_key)
295                 return 0;
296         if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0)
297                 return -E_KEY_PERM;
298         return 1;
299 }
300
301 void hash_to_asc(unsigned char *hash, char *asc)
302 {
303         int i;
304         const char hexchar[] = "0123456789abcdef";
305
306         for (i = 0; i < HASH_SIZE; i++) {
307                 asc[2 * i] = hexchar[hash[i] >> 4];
308                 asc[2 * i + 1] = hexchar[hash[i] & 0xf];
309         }
310         asc[2 * HASH_SIZE] = '\0';
311 }
312
313 int hash_compare(unsigned char *h1, unsigned char *h2)
314 {
315         int i;
316
317         for (i = 0; i < HASH_SIZE; i++) {
318                 if (h1[i] < h2[i])
319                         return -1;
320                 if (h1[i] > h2[i])
321                         return 1;
322         }
323         return 0;
324 }
325
326 int sc_recv_buffer(struct stream_cipher_context *scc, char *buf, size_t size)
327 {
328         int n;
329
330         assert(size);
331         n = sc_recv_bin_buffer(scc, buf, size - 1);
332         if (n >= 0)
333                 buf[n] = '\0';
334         else
335                 *buf = '\0';
336         return n;
337 }
338
339 int sc_send_buffer(struct stream_cipher_context *scc, char *buf)
340 {
341         return sc_send_bin_buffer(scc, buf, strlen(buf));
342 }
343
344 __printf_2_3 int sc_send_va_buffer(struct stream_cipher_context *scc,
345                 const char *fmt, ...)
346 {
347         char *msg;
348         int ret;
349
350         PARA_VSPRINTF(fmt, msg);
351         ret = sc_send_buffer(scc, msg);
352         free(msg);
353         return ret;
354 }