tests: Add tests for mpi_cmp.
[libgcrypt.git] / random / random-daemon.c
1 /* random-daemon.c  - Access to the external random daemon
2  * Copyright (C) 2006  Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 /*
22    The functions here are used by random.c to divert calls to an
23    external random number daemon.  The actual daemon we use is
24    gcryptrnd.  Such a daemon is useful to keep a persistent pool in
25    memory over invocations of a single application and to allow
26    prioritizing access to the actual entropy sources.  The drawback is
27    that we need to use IPC (i.e. unix domain socket) to convey
28    sensitive data.
29  */
30
31 #error This dameon needs to be fixed due to the ath changes
32
33 #include <config.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <assert.h>
37 #include <string.h>
38 #include <sys/socket.h>
39 #include <sys/un.h>
40 #include <errno.h>
41 #include <unistd.h>
42
43 #include "g10lib.h"
44 #include "random.h"
45 #include "ath.h"
46
47 \f
48
49 /* This is default socket name we use in case the provided socket name
50    is NULL.  */
51 #define RANDOM_DAEMON_SOCKET "/var/run/libgcrypt/S.gcryptrnd"
52
53 /* The lock serializing access to the daemon.  */
54 static ath_mutex_t daemon_lock = ATH_MUTEX_INITIALIZER;
55
56 /* The socket connected to the daemon.  */
57 static int daemon_socket = -1;
58
59 /* Creates a socket connected to the daemon.  On success, store the
60    socket fd in *SOCK.  Returns error code.  */
61 static gcry_error_t
62 connect_to_socket (const char *socketname, int *sock)
63 {
64   struct sockaddr_un *srvr_addr;
65   socklen_t addrlen;
66   gcry_error_t err;
67   int fd;
68   int rc;
69
70   srvr_addr = NULL;
71
72   /* Create a socket. */
73   fd = socket (AF_UNIX, SOCK_STREAM, 0);
74   if (fd == -1)
75     {
76       log_error ("can't create socket: %s\n", strerror (errno));
77       err = gcry_error_from_errno (errno);
78       goto out;
79     }
80
81   /* Set up address.  */
82   srvr_addr = gcry_malloc (sizeof *srvr_addr);
83   if (! srvr_addr)
84     {
85       log_error ("malloc failed: %s\n", strerror (errno));
86       err = gcry_error_from_errno (errno);
87       goto out;
88     }
89   memset (srvr_addr, 0, sizeof *srvr_addr);
90   srvr_addr->sun_family = AF_UNIX;
91   if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
92     {
93       log_error ("socket name `%s' too long\n", socketname);
94       err = gcry_error (GPG_ERR_ENAMETOOLONG);
95       goto out;
96     }
97   strcpy (srvr_addr->sun_path, socketname);
98   addrlen = (offsetof (struct sockaddr_un, sun_path)
99              + strlen (srvr_addr->sun_path) + 1);
100
101   /* Connect socket.  */
102   rc = connect (fd, (struct sockaddr *) srvr_addr, addrlen);
103   if (rc == -1)
104     {
105       log_error ("error connecting socket `%s': %s\n",
106                  srvr_addr->sun_path, strerror (errno));
107       err = gcry_error_from_errno (errno);
108       goto out;
109     }
110
111   err = 0;
112
113  out:
114
115   gcry_free (srvr_addr);
116   if (err)
117     {
118       close (fd);
119       fd = -1;
120     }
121   *sock = fd;
122
123   return err;
124 }
125
126
127 /* Initialize basics of this module. This should be viewed as a
128    constructor to prepare locking. */
129 void
130 _gcry_daemon_initialize_basics (void)
131 {
132   static int initialized;
133   int err;
134
135   if (!initialized)
136     {
137       initialized = 1;
138       err = ath_mutex_init (&daemon_lock);
139       if (err)
140         log_fatal ("failed to create the daemon lock: %s\n", strerror (err) );
141     }
142 }
143
144
145
146 /* Send LENGTH bytes of BUFFER to file descriptor FD.  Returns 0 on
147    success or another value on write error. */
148 static int
149 writen (int fd, const void *buffer, size_t length)
150 {
151   ssize_t n;
152
153   while (length)
154     {
155       do
156         n = ath_write (fd, buffer, length);
157       while (n < 0 && errno == EINTR);
158       if (n < 0)
159          {
160            log_error ("write error: %s\n", strerror (errno));
161            return -1; /* write error */
162          }
163       length -= n;
164       buffer = (const char*)buffer + n;
165     }
166   return 0;  /* Okay */
167 }
168
169 static int
170 readn (int fd, void *buf, size_t buflen, size_t *ret_nread)
171 {
172   size_t nleft = buflen;
173   int nread;
174   char *p;
175
176   p = buf;
177   while (nleft > 0)
178     {
179       nread = ath_read (fd, buf, nleft);
180       if (nread < 0)
181         {
182           if (nread == EINTR)
183             nread = 0;
184           else
185             return -1;
186         }
187       else if (!nread)
188         break; /* EOF */
189       nleft -= nread;
190       buf = (char*)buf + nread;
191     }
192   if (ret_nread)
193     *ret_nread = buflen - nleft;
194   return 0;
195 }
196
197 /* This functions requests REQ_NBYTES from the daemon.  If NONCE is
198    true, the data should be suited for a nonce.  If NONCE is FALSE,
199    data of random level LEVEL will be generated.  The retrieved random
200    data will be stored in BUFFER.  Returns error code.  */
201 static gcry_error_t
202 call_daemon (const char *socketname,
203              void *buffer, size_t req_nbytes, int nonce,
204              enum gcry_random_level level)
205 {
206   static int initialized;
207   unsigned char buf[255];
208   gcry_error_t err = 0;
209   size_t nbytes;
210   size_t nread;
211   int rc;
212
213   if (!req_nbytes)
214     return 0;
215
216   ath_mutex_lock (&daemon_lock);
217
218   /* Open the socket if that has not been done. */
219   if (!initialized)
220     {
221       initialized = 1;
222       err = connect_to_socket (socketname ? socketname : RANDOM_DAEMON_SOCKET,
223                                &daemon_socket);
224       if (err)
225         {
226           daemon_socket = -1;
227           log_info ("not using random daemon\n");
228           ath_mutex_unlock (&daemon_lock);
229           return err;
230         }
231     }
232
233   /* Check that we have a valid socket descriptor. */
234   if ( daemon_socket == -1 )
235     {
236       ath_mutex_unlock (&daemon_lock);
237       return gcry_error (GPG_ERR_INTERNAL);
238     }
239
240
241   /* Do the real work.  */
242
243   do
244     {
245       /* Process in chunks.  */
246       nbytes = req_nbytes > sizeof (buf) ? sizeof (buf) : req_nbytes;
247       req_nbytes -= nbytes;
248
249       /* Construct request.  */
250       buf[0] = 3;
251       if (nonce)
252         buf[1] = 10;
253       else if (level == GCRY_VERY_STRONG_RANDOM)
254         buf[1] = 12;
255       else if (level == GCRY_STRONG_RANDOM)
256         buf[1] = 11;
257       buf[2] = nbytes;
258
259       /* Send request.  */
260       rc = writen (daemon_socket, buf, 3);
261       if (rc == -1)
262         {
263           err = gcry_error_from_errno (errno);
264           break;
265         }
266
267       /* Retrieve response.  */
268
269       rc = readn (daemon_socket, buf, 2, &nread);
270       if (rc == -1)
271         {
272           err = gcry_error_from_errno (errno);
273           log_error ("read error: %s\n", gcry_strerror (err));
274           break;
275         }
276       if (nread && buf[0])
277         {
278           log_error ("random daemon returned error code %d\n", buf[0]);
279           err = gcry_error (GPG_ERR_INTERNAL); /* ? */
280           break;
281         }
282       if (nread != 2)
283         {
284           log_error ("response too small\n");
285           err = gcry_error (GPG_ERR_PROTOCOL_VIOLATION); /* ? */
286           break;
287         }
288
289       /*      if (1)*/                  /* Do this in verbose mode? */
290       /*        log_info ("received response with %d bytes of data\n", buf[1]);*/
291
292       if (buf[1] < nbytes)
293         {
294           log_error ("error: server returned less bytes than requested\n");
295           err = gcry_error (GPG_ERR_PROTOCOL_VIOLATION); /* ? */
296           break;
297         }
298       else if (buf[1] > nbytes)
299         {
300           log_error ("warning: server returned more bytes than requested\n");
301           err = gcry_error (GPG_ERR_PROTOCOL_VIOLATION); /* ? */
302           break;
303         }
304
305       assert (nbytes <= sizeof (buf));
306
307       rc = readn (daemon_socket, buf, nbytes, &nread);
308       if (rc == -1)
309         {
310           err = gcry_error_from_errno (errno);
311           log_error ("read error: %s\n", gcry_strerror (err));
312           break;
313         }
314
315       if (nread != nbytes)
316         {
317           log_error ("too little random data read\n");
318           err = gcry_error (GPG_ERR_INTERNAL);
319           break;
320         }
321
322       /* Successfuly read another chunk of data.  */
323       memcpy (buffer, buf, nbytes);
324       buffer = ((char *) buffer) + nbytes;
325     }
326   while (req_nbytes);
327
328   ath_mutex_unlock (&daemon_lock);
329
330   return err;
331 }
332
333 /* Internal function to fill BUFFER with LENGTH bytes of random.  We
334    support GCRY_STRONG_RANDOM and GCRY_VERY_STRONG_RANDOM here.
335    Return 0 on success. */
336 int
337 _gcry_daemon_randomize (const char *socketname,
338                         void *buffer, size_t length,
339                         enum gcry_random_level level)
340 {
341   gcry_error_t err;
342
343   err = call_daemon (socketname, buffer, length, 0, level);
344
345   return err ? -1 : 0;
346 }
347
348 /* END */