1 /*
2  *  Copyright (C) 2007 Red Hat, Inc.
3  *
4  *  Permission is hereby granted, free of charge, to any person obtaining a
5  *  copy of this software and associated documentation files (the
6  *  "Software"), to deal in the Software without restriction, including
7  *  without limitation the rights to use, copy, modify, merge, publish,
8  *  distribute, sublicense, and/or sell copies of the Software, and to
9  *  permit persons to whom the Software is furnished to do so, subject
10  *  to the following conditions:
11  *
12  *  The above copyright notice and this permission notice shall be
13  *  included in all copies or substantial portions of the Software.
14  *
15  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  *  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  *  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  *  SOFTWARE.
23 */
24 
25 #include <unistd.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include "nss_compat_ossl.h"
29 
RAND_add(const void * buf,int num,double entropy)30 void RAND_add(const void *buf, int num, double entropy)
31 {
32     PK11_RandomUpdate((void *)buf, num);
33 
34     return;
35 }
36 
RAND_status(void)37 int RAND_status(void)
38 {
39     /* NSS does its own seeding so this is always true */
40     return 1;
41 }
42 
RAND_load_file(const char * file,long max_bytes)43 int RAND_load_file(const char *file, long max_bytes)
44 {
45     long totalread = 0;
46     long numread = 0;
47     long toread = 0;
48     FILE *fp;
49     char buf[1024];
50     struct stat st;
51 
52     if (file == NULL)
53         return 0;
54 
55     if (stat(file, &st) < 0)
56         return 0;
57 
58     if (!S_ISREG(st.st_mode)) {
59         if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
60             if (max_bytes == -1)
61                 max_bytes = 1024; /* don't read everything from /dev/foo */
62         } else
63             return 0;
64     }
65 
66     if ((fp = fopen(file, "rb")) != NULL) {
67         while (!feof(fp) && (totalread < max_bytes)) {
68             if (max_bytes > 0)
69                 toread = (max_bytes - totalread > 1024) ? 1024 : max_bytes - totalread;
70             else
71                 toread = 1024;
72             numread = fread(buf, 1, toread, fp);
73             if (numread <= 0)
74                 break;
75             PK11_RandomUpdate(buf, numread);
76             totalread += numread;
77         }
78         fclose(fp);
79     }
80 
81     return totalread;
82 }
83 
84 /* According to man page */
85 #define RAND_WRITE_BYTES 1024
86 
RAND_write_file(const char * file)87 int RAND_write_file(const char *file)
88 {
89     unsigned char buf[RAND_WRITE_BYTES];
90     int total = 0;
91     size_t numwrite;
92     FILE *fp;
93 
94     if ((fp = fopen(file, "wb")) != NULL) {
95         chmod(file, 0600);
96 	if (PK11_GenerateRandom(buf, sizeof (buf)) == SECSuccess) {
97 	    total = sizeof (buf);
98             numwrite = fwrite(buf, 1, total, fp);
99             if (numwrite <= 0)
100                 total = 0;
101 	}
102 	fclose(fp);
103     }
104     return total;
105 }
106 
RAND_file_name(char * file,size_t num)107 const char *RAND_file_name(char *file, size_t num)
108 {
109     char *filename = NULL;
110     file[0] = '\0';
111 
112     /* FIXME: Check $HOME/.rnd too */
113     filename = getenv("RANDFILE");
114 
115     if (filename && strlen(filename) < num)
116         PL_strncpy(file, filename, num);
117     else {
118         filename = getenv("HOME");
119         if (filename && (strlen(filename) + 6 < num)) {
120             PR_snprintf(file, num-1, "%s/.rnd", filename);
121         }
122     }
123 
124     return file;
125 }
126 
RAND_egd(const char * path)127 int RAND_egd(const char *path)
128 {
129     return -1; /* EGD not supported */
130 }
131