~ubuntu-branches/debian/stretch/uswsusp/stretch

« back to all changes in this revision

Viewing changes to suspend-cvs20060928/keygen.c

  • Committer: Bazaar Package Importer
  • Author(s): Christian Perrier
  • Date: 2008-08-20 09:09:13 UTC
  • mfrom: (0.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20080820090913-0eahue1zo8egcxls
Tags: 0.8-1.1
* Non-maintainer upload to fix pending l10n issues.
* Remove extra and useless debian/po/ff/ directory
* Debconf translation updates:
  - Japanese. Closes: #489939
  - German. Closes: #493747
  - French. Closes: #493771
  - Romanian. Closes: #493772
  - Galician. Closes: #494050
  - Finnish. Closes: #494087
  - Italian. Closes: #494096
  - Basque. Closes: #494277
  - Basque. Closes: #494277
  - Czech. Closes: #494410
  - Swedish. Closes: #494412
  - Russian. Closes: #495412
  - Portuguese. Closes: #495451
  - Spanish. Closes: #495499
  - Slovak. Closes: #495516

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * keygen.c
3
 
 *
4
 
 * RSA key generator for the suspend and resume tools.
5
 
 *
6
 
 * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
7
 
 *
8
 
 * This file is released under the GPLv2.
9
 
 *
10
 
 */
11
 
 
12
 
#include <sys/types.h>
13
 
#include <sys/stat.h>
14
 
#include <fcntl.h>
15
 
#include <unistd.h>
16
 
#include <errno.h>
17
 
#include <stdlib.h>
18
 
#include <stdio.h>
19
 
#include <string.h>
20
 
#include <termios.h>
21
 
 
22
 
#include "md5.h"
23
 
#include "encrypt.h"
24
 
 
25
 
#define MIN_KEY_BITS    1024
26
 
#define MAX_KEY_BITS    4096
27
 
#define MAX_OUT_SIZE    (sizeof(struct RSA_data))
28
 
#define MAX_STR_LEN     256
29
 
#define DEFAULT_FILE    "suspend.key"
30
 
 
31
 
static char in_buffer[MAX_STR_LEN];
32
 
static char pass_buf[MAX_STR_LEN];
33
 
static struct RSA_data rsa;
34
 
static unsigned char encrypt_buffer[RSA_DATA_SIZE];
35
 
 
36
 
int main(int argc, char *argv[])
37
 
{
38
 
        gcry_ac_data_t rsa_data_set;
39
 
        gcry_ac_handle_t rsa_hd;
40
 
        gcry_ac_key_t rsa_priv;
41
 
        gcry_ac_key_pair_t rsa_key_pair;
42
 
        gcry_mpi_t mpi;
43
 
        size_t offset;
44
 
        int len = MIN_KEY_BITS, ret = EXIT_SUCCESS;
45
 
        struct termios termios;
46
 
        char *vrfy_buf;
47
 
        struct md5_ctx ctx;
48
 
        unsigned char key_buf[PK_KEY_SIZE];
49
 
        gcry_cipher_hd_t sym_hd;
50
 
        unsigned char ivec[PK_CIPHER_BLOCK];
51
 
        unsigned short size;
52
 
        int j, fd;
53
 
 
54
 
        printf("libgcrypt version: %s\n", gcry_check_version(NULL));
55
 
        gcry_control(GCRYCTL_INIT_SECMEM, 4096, 0);
56
 
        ret = gcry_ac_open(&rsa_hd, GCRY_AC_RSA, 0);
57
 
        if (ret)
58
 
                return ret;
59
 
 
60
 
        do {
61
 
                printf("Key bits (between %d and %d inclusive) [%d]: ",
62
 
                        MIN_KEY_BITS, MAX_KEY_BITS, len);
63
 
                fgets(in_buffer, MAX_STR_LEN, stdin);
64
 
                if (strlen(in_buffer) && *in_buffer != '\n')
65
 
                        sscanf(in_buffer, "%d", &len);
66
 
        } while (len < MIN_KEY_BITS || len > MAX_KEY_BITS);
67
 
 
68
 
Retry:
69
 
        printf("Generating %d-bit RSA keys.  Please wait.\n", len);
70
 
        ret = gcry_ac_key_pair_generate(rsa_hd, len, NULL, &rsa_key_pair, NULL);
71
 
        if (ret) {
72
 
                fprintf(stderr, "Key generation failed: %s\n", gcry_strerror(ret));
73
 
                ret = EXIT_FAILURE;
74
 
                goto Close_RSA;
75
 
        }
76
 
        printf("Testing the private key.  Please wait.\n");
77
 
        rsa_priv = gcry_ac_key_pair_extract(rsa_key_pair, GCRY_AC_KEY_SECRET);
78
 
        ret = gcry_ac_key_test(rsa_hd, rsa_priv);
79
 
        if (ret) {
80
 
                printf("RSA key test failed.  Retrying.\n");
81
 
                goto Retry;
82
 
        }
83
 
 
84
 
        rsa_data_set = gcry_ac_key_data_get(rsa_priv);
85
 
        if (gcry_ac_data_length(rsa_data_set) != RSA_FIELDS) {
86
 
                fprintf(stderr, "Wrong number of key fields\n");
87
 
                ret = -EINVAL;
88
 
                goto Free_RSA;
89
 
        }
90
 
 
91
 
        /* Convert the key length into bytes */
92
 
        size = (len + 7) >> 3;
93
 
        /* Copy the public key components to struct RSA_data */
94
 
        offset = 0;
95
 
        for (j = 0; j < RSA_FIELDS_PUB; j++) {
96
 
                char *str;
97
 
                size_t s;
98
 
 
99
 
                if (offset + size >= RSA_DATA_SIZE)
100
 
                        goto Free_RSA;
101
 
 
102
 
                gcry_ac_data_get_index(rsa_data_set, GCRY_AC_FLAG_COPY, j,
103
 
                                        (const char **)&str, &mpi);
104
 
                gcry_mpi_print(GCRYMPI_FMT_USG, rsa.data + offset,
105
 
                                        size, &s, mpi);
106
 
                rsa.field[j][0] = str[0];
107
 
                rsa.field[j][1] = '\0';
108
 
                rsa.size[j] = s;
109
 
                offset += s;
110
 
                gcry_mpi_release(mpi);
111
 
                gcry_free(str);
112
 
        }
113
 
 
114
 
        tcgetattr(0, &termios);
115
 
        termios.c_lflag &= ~ECHO;
116
 
        termios.c_lflag |= ICANON | ECHONL;
117
 
        tcsetattr(0, TCSANOW, &termios);
118
 
        vrfy_buf = (char *)encrypt_buffer;
119
 
        do {
120
 
                do {
121
 
                        printf("Passphrase please (must be non-empty): ");
122
 
                        fgets(pass_buf, MAX_STR_LEN, stdin);
123
 
                        len = strlen(pass_buf) - 1;
124
 
                } while (len <= 0);
125
 
                if (pass_buf[len] == '\n')
126
 
                        pass_buf[len] = '\0';
127
 
                printf("Confirm passphrase: ");
128
 
                fgets(vrfy_buf, MAX_STR_LEN, stdin);
129
 
                if (vrfy_buf[len] == '\n')
130
 
                        vrfy_buf[len] = '\0';
131
 
        } while (strncmp(pass_buf, vrfy_buf, MAX_STR_LEN));
132
 
        termios.c_lflag |= ECHO;
133
 
        tcsetattr(0, TCSANOW, &termios);
134
 
 
135
 
        memset(ivec, 0, PK_CIPHER_BLOCK);
136
 
        strncpy((char *)ivec, pass_buf, PK_CIPHER_BLOCK);
137
 
        md5_init_ctx(&ctx);
138
 
        md5_process_bytes(pass_buf, strlen(pass_buf), &ctx);
139
 
        md5_finish_ctx(&ctx, key_buf);
140
 
 
141
 
        /* First, we encrypt the key test */
142
 
        ret = gcry_cipher_open(&sym_hd, PK_CIPHER, GCRY_CIPHER_MODE_CFB,
143
 
                                GCRY_CIPHER_SECURE);
144
 
        if (ret)
145
 
                goto Free_RSA;
146
 
 
147
 
        ret = gcry_cipher_setkey(sym_hd, key_buf, PK_KEY_SIZE);
148
 
        if (!ret)
149
 
                ret = gcry_cipher_setiv(sym_hd, ivec, PK_CIPHER_BLOCK);
150
 
 
151
 
        if (!ret)
152
 
                ret = gcry_cipher_encrypt(sym_hd, rsa.key_test, KEY_TEST_SIZE,
153
 
                                        KEY_TEST_DATA, KEY_TEST_SIZE);
154
 
 
155
 
        gcry_cipher_close(sym_hd);
156
 
        if (ret)
157
 
                goto Free_RSA;
158
 
 
159
 
        /* Now, we can encrypt the private RSA key */
160
 
        ret = gcry_cipher_open(&sym_hd, PK_CIPHER, GCRY_CIPHER_MODE_CFB,
161
 
                                GCRY_CIPHER_SECURE);
162
 
        if (ret)
163
 
                goto Free_RSA;
164
 
 
165
 
        ret = gcry_cipher_setkey(sym_hd, key_buf, PK_KEY_SIZE);
166
 
        if (!ret)
167
 
                ret = gcry_cipher_setiv(sym_hd, ivec, PK_CIPHER_BLOCK);
168
 
 
169
 
        if (ret)
170
 
                goto Free_sym;
171
 
 
172
 
        /* Copy the private key components (encrypted) to struct RSA_data */
173
 
        for (j = RSA_FIELDS_PUB; j < RSA_FIELDS; j++) {
174
 
                char *str;
175
 
                size_t s;
176
 
 
177
 
                if (offset + size >= RSA_DATA_SIZE)
178
 
                        goto Free_sym;
179
 
 
180
 
                gcry_ac_data_get_index(rsa_data_set, GCRY_AC_FLAG_COPY, j,
181
 
                                        (const char **)&str, &mpi);
182
 
                gcry_mpi_print(GCRYMPI_FMT_USG, rsa.data + offset,
183
 
                                        size, &s, mpi);
184
 
 
185
 
                /* We encrypt the data in place */
186
 
                ret = gcry_cipher_encrypt(sym_hd, rsa.data + offset, s, NULL, 0);
187
 
                if (ret)
188
 
                        goto Free_sym;
189
 
 
190
 
                rsa.field[j][0] = str[0];
191
 
                rsa.field[j][1] = '\0';
192
 
                rsa.size[j] = s;
193
 
                offset += s;
194
 
                gcry_mpi_release(mpi);
195
 
                gcry_free(str);
196
 
        }
197
 
 
198
 
        size = offset + sizeof(struct RSA_data) - RSA_DATA_SIZE;
199
 
 
200
 
        printf("File name [%s]: ", DEFAULT_FILE);
201
 
        fgets(in_buffer, MAX_STR_LEN, stdin);
202
 
        if (!strlen(in_buffer) || *in_buffer == '\n')
203
 
                strcpy(in_buffer, DEFAULT_FILE);
204
 
        else if (in_buffer[strlen(in_buffer)-1] == '\n')
205
 
                in_buffer[strlen(in_buffer)-1] = '\0';
206
 
        fd = open(in_buffer, O_RDWR | O_CREAT | O_TRUNC, 00600);
207
 
        if (fd >= 0) {
208
 
                write(fd, &rsa, size);
209
 
                close(fd);
210
 
        } else {
211
 
                fprintf(stderr, "Could not open the file %s\n", in_buffer);
212
 
                ret = EXIT_FAILURE;
213
 
        }
214
 
Free_sym:
215
 
        gcry_cipher_close(sym_hd);
216
 
Free_RSA:
217
 
        gcry_ac_data_destroy(rsa_data_set);
218
 
Close_RSA:
219
 
        gcry_ac_close(rsa_hd);
220
 
 
221
 
        return ret;
222
 
}