19
19
20
20
21
21
#include <stdio.h>
22
+ #include <string.h>
22
23
#include <sodium.h>
23
24
#include <fcntl.h>
24
25
#include <unistd.h>
25
26
26
27
#include <sys/ioctl.h>
27
28
#include <linux/random.h>
28
29
29
- int main (void )
30
+ int main (int argc , char * * argv )
30
31
{
31
32
unsigned char drone_publickey [crypto_box_PUBLICKEYBYTES ];
32
33
unsigned char drone_secretkey [crypto_box_SECRETKEYBYTES ];
33
34
unsigned char gs_publickey [crypto_box_PUBLICKEYBYTES ];
34
35
unsigned char gs_secretkey [crypto_box_SECRETKEYBYTES ];
35
36
FILE * fp ;
37
+ char * password = NULL ;
36
38
39
+ if (argc == 2 )
40
+ {
41
+ password = argv [1 ];
42
+ }
43
+
44
+ if (argc > 2 )
45
+ {
46
+ fprintf (stderr , "Usage: %s [password]\n" , argv [0 ]);
47
+ return 1 ;
48
+ }
49
+
50
+ // check for enough entropy and warn if sodium_init() can freeze
37
51
{
38
52
int fd ;
39
53
int c ;
40
54
41
- if ((fd = open ("/dev/random" , O_RDONLY )) != -1 ) {
42
- if (ioctl (fd , RNDGETENTCNT , & c ) == 0 && c < 160 ) {
55
+ if ((fd = open ("/dev/random" , O_RDONLY )) != -1 )
56
+ {
57
+ if (ioctl (fd , RNDGETENTCNT , & c ) == 0 && c < 160 )
58
+ {
43
59
fprintf (stderr , "This system doesn't provide enough entropy to quickly generate high-quality random numbers.\n"
44
60
"Installing the rng-utils/rng-tools, jitterentropy or haveged packages may help.\n"
45
61
"On virtualized Linux environments, also consider using virtio-rng.\n"
46
- "The service will not start until enough entropy has been collected.\n" );
62
+ "This command will wait until enough entropy has been collected.\n" );
47
63
}
48
64
(void ) close (fd );
49
65
}
@@ -55,11 +71,38 @@ int main(void)
55
71
return 1 ;
56
72
}
57
73
58
- if (crypto_box_keypair (drone_publickey , drone_secretkey ) != 0 ||
59
- crypto_box_keypair (gs_publickey , gs_secretkey ) != 0 )
74
+ if (password != NULL )
60
75
{
61
- fprintf (stderr , "Unable to generate keys\n" );
62
- return 1 ;
76
+ unsigned char salt [crypto_pwhash_argon2i_SALTBYTES ] = \
77
+ {'w' ,'i' ,'f' ,'i' ,'b' ,'r' ,'o' ,'a' ,'d' ,'c' ,'a' ,'s' ,'t' ,'k' ,'e' ,'y' };
78
+
79
+ unsigned char seed [crypto_box_SEEDBYTES ];
80
+ if (crypto_pwhash_argon2i
81
+ (seed , sizeof (seed ), password , strlen (password ), salt ,
82
+ crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE , // Low CPU usage
83
+ crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE , // 64MB or RAM is required
84
+ crypto_pwhash_ALG_ARGON2I13 ) != 0 ) // Ensure compatibility with old libsodium versions
85
+ {
86
+ fprintf (stderr , "Unable to derive seed from password\n" );
87
+ return 1 ;
88
+ }
89
+ if (crypto_box_seed_keypair (drone_publickey , drone_secretkey , seed ) != 0 ||
90
+ crypto_box_seed_keypair (gs_publickey , gs_secretkey , seed ) != 0 )
91
+ {
92
+ fprintf (stderr , "Unable to derive keys\n" );
93
+ return 1 ;
94
+ }
95
+ fprintf (stderr , "Keypair derived from provided password\n" );
96
+ }
97
+ else
98
+ {
99
+ if (crypto_box_keypair (drone_publickey , drone_secretkey ) != 0 ||
100
+ crypto_box_keypair (gs_publickey , gs_secretkey ) != 0 )
101
+ {
102
+ fprintf (stderr , "Unable to generate keys\n" );
103
+ return 1 ;
104
+ }
105
+ fprintf (stderr , "Keypair generated from random seed\n" );
63
106
}
64
107
65
108
if ((fp = fopen ("drone.key" , "w" )) == NULL )
0 commit comments