]> git.tuebingen.mpg.de Git - paraslash.git/blob - crypt_common.c
blob: Remove some unnecessary casts for arguments to read_u32().
[paraslash.git] / crypt_common.c
1 /*
2  * Copyright (C) 2005 Andre Noll <maan@tuebingen.mpg.de>
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
11 #include "para.h"
12 #include "error.h"
13 #include "string.h"
14 #include "crypt.h"
15 #include "crypt_backend.h"
16 #include "portable_io.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  * Sanity checks for the header of an ssh key.
51  *
52  * \param blob The buffer.
53  * \param blen The number of bytes of \a blob.
54  *
55  * This performs some checks to make sure we really have an ssh key. It also
56  * computes the offset in bytes of the start of the key values (modulus,
57  * exponent..).
58  *
59  * \return The number of bytes to skip until the start of the first encoded
60  * number (usually 11).
61  */
62 int check_ssh_key_header(const unsigned char *blob, int blen)
63 {
64         const unsigned char *p = blob, *end = blob + blen;
65         uint32_t rlen;
66
67         if (p + 4 > end)
68                 return -E_SSH_KEY_HEADER;
69         rlen = read_u32_be(p);
70         p += 4;
71         if (p + rlen < p)
72                 return -E_SSH_KEY_HEADER;
73         if (p + rlen > end)
74                 return -E_SSH_KEY_HEADER;
75         if (rlen < strlen(KEY_TYPE_TXT))
76                 return -E_SSH_KEY_HEADER;
77         PARA_DEBUG_LOG("type: %s, rlen: %u\n", p, rlen);
78         if (strncmp((char *)p, KEY_TYPE_TXT, strlen(KEY_TYPE_TXT)))
79                 return -E_SSH_KEY_HEADER;
80         return 4 + rlen;
81 }
82
83 /**
84  * Check existence and permissions of a private key file.
85  *
86  * \param file The path of the key file.
87  *
88  * This checks whether the file exists and its permissions are restrictive
89  * enough. It is considered an error if we own the file and it is readable for
90  * others.
91  *
92  * \return Standard.
93  */
94 int check_private_key_file(const char *file)
95 {
96         struct stat st;
97
98         if (stat(file, &st) != 0)
99                 return -ERRNO_TO_PARA_ERROR(errno);
100         if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0)
101                 return -E_KEY_PERM;
102         return 1;
103 }
104
105 void hash_to_asc(unsigned char *hash, char *asc)
106 {
107         int i;
108         const char hexchar[] = "0123456789abcdef";
109
110         for (i = 0; i < HASH_SIZE; i++) {
111                 asc[2 * i] = hexchar[hash[i] >> 4];
112                 asc[2 * i + 1] = hexchar[hash[i] & 0xf];
113         }
114         asc[2 * HASH_SIZE] = '\0';
115 }
116
117 int hash_compare(unsigned char *h1, unsigned char *h2)
118 {
119         int i;
120
121         for (i = 0; i < HASH_SIZE; i++) {
122                 if (h1[i] < h2[i])
123                         return -1;
124                 if (h1[i] > h2[i])
125                         return 1;
126         }
127         return 0;
128 }