~ubuntu-branches/ubuntu/raring/gnupg2/raring-security

« back to all changes in this revision

Viewing changes to .pc/gnupg2-fix-libgcrypt.diff/g10/pkglue.c

  • Committer: Package Import Robot
  • Author(s): Sebastien Bacher
  • Date: 2012-11-06 11:25:58 UTC
  • mfrom: (1.1.16) (7.1.8 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20121106112558-lkpndvv4gqthgrn4
Tags: 2.0.19-1ubuntu1
* Resynchronize on Debian, remaining changes:
  - Add udev rules to give gpg access to some smartcard readers;
    Debian #543217.
    . debian/gnupg2.dev: udev rules to set ACLs on SCM smartcard readers.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* pkglue.c - public key operations glue code
2
 
 *      Copyright (C) 2000, 2003 Free Software Foundation, Inc.
3
 
 *
4
 
 * This file is part of GnuPG.
5
 
 *
6
 
 * GnuPG is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 3 of the License, or
9
 
 * (at your option) any later version.
10
 
 *
11
 
 * GnuPG 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 General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18
 
 */
19
 
 
20
 
#include <config.h>
21
 
#include <stdio.h>
22
 
#include <stdlib.h>
23
 
#include <string.h>
24
 
#include <errno.h>
25
 
#include <assert.h>
26
 
 
27
 
#include "gpg.h"
28
 
#include "util.h"
29
 
#include "pkglue.h"
30
 
 
31
 
 
32
 
static gcry_mpi_t
33
 
mpi_from_sexp (gcry_sexp_t sexp, const char * item)
34
 
{
35
 
  gcry_sexp_t list;
36
 
  gcry_mpi_t data;
37
 
  
38
 
  list = gcry_sexp_find_token (sexp, item, 0);
39
 
  assert (list);
40
 
  data = gcry_sexp_nth_mpi (list, 1, 0);
41
 
  assert (data);
42
 
  gcry_sexp_release (list);
43
 
  return data;
44
 
}
45
 
 
46
 
 
47
 
/****************
48
 
 * Emulate our old PK interface here - sometime in the future we might
49
 
 * change the internal design to directly fit to libgcrypt.
50
 
 */
51
 
int
52
 
pk_sign (int algo, gcry_mpi_t * data, gcry_mpi_t hash, gcry_mpi_t * skey)
53
 
{
54
 
  gcry_sexp_t s_sig, s_hash, s_skey;
55
 
  int rc;
56
 
 
57
 
  /* make a sexp from skey */
58
 
  if (algo == GCRY_PK_DSA)
59
 
    {
60
 
      rc = gcry_sexp_build (&s_skey, NULL,
61
 
                            "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
62
 
                            skey[0], skey[1], skey[2], skey[3], skey[4]);
63
 
    }
64
 
  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S)
65
 
    {
66
 
      rc = gcry_sexp_build (&s_skey, NULL,
67
 
                            "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
68
 
                            skey[0], skey[1], skey[2], skey[3], skey[4],
69
 
                            skey[5]);
70
 
    }
71
 
  else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
72
 
    {
73
 
      rc = gcry_sexp_build (&s_skey, NULL,
74
 
                            "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
75
 
                            skey[0], skey[1], skey[2], skey[3]);
76
 
    }
77
 
  else
78
 
    return GPG_ERR_PUBKEY_ALGO;
79
 
 
80
 
  if (rc)
81
 
    BUG ();
82
 
 
83
 
  /* put hash into a S-Exp s_hash */
84
 
  if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
85
 
    BUG ();
86
 
 
87
 
  rc = gcry_pk_sign (&s_sig, s_hash, s_skey);
88
 
  gcry_sexp_release (s_hash);
89
 
  gcry_sexp_release (s_skey);
90
 
 
91
 
  if (rc)
92
 
    ;
93
 
  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S)
94
 
    data[0] = mpi_from_sexp (s_sig, "s");
95
 
  else
96
 
    {
97
 
      data[0] = mpi_from_sexp (s_sig, "r");
98
 
      data[1] = mpi_from_sexp (s_sig, "s");
99
 
    }
100
 
 
101
 
  gcry_sexp_release (s_sig);
102
 
  return rc;
103
 
}
104
 
 
105
 
/****************
106
 
 * Emulate our old PK interface here - sometime in the future we might
107
 
 * change the internal design to directly fit to libgcrypt.
108
 
 */
109
 
int
110
 
pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey)
111
 
{
112
 
  gcry_sexp_t s_sig, s_hash, s_pkey;
113
 
  int rc;
114
 
 
115
 
  /* make a sexp from pkey */
116
 
  if (algo == GCRY_PK_DSA)
117
 
    {
118
 
      rc = gcry_sexp_build (&s_pkey, NULL,
119
 
                            "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
120
 
                            pkey[0], pkey[1], pkey[2], pkey[3]);
121
 
    }
122
 
  else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
123
 
    {
124
 
      rc = gcry_sexp_build (&s_pkey, NULL,
125
 
                            "(public-key(elg(p%m)(g%m)(y%m)))",
126
 
                            pkey[0], pkey[1], pkey[2]);
127
 
    }
128
 
  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S)
129
 
    {
130
 
      rc = gcry_sexp_build (&s_pkey, NULL,
131
 
                            "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]);
132
 
    }
133
 
  else
134
 
    return GPG_ERR_PUBKEY_ALGO;
135
 
 
136
 
  if (rc)
137
 
    BUG ();  /* gcry_sexp_build should never fail.  */
138
 
 
139
 
  /* put hash into a S-Exp s_hash */
140
 
  if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
141
 
    BUG (); /* gcry_sexp_build should never fail.  */
142
 
 
143
 
  /* Put data into a S-Exp s_sig. */
144
 
  s_sig = NULL;
145
 
  if (algo == GCRY_PK_DSA)
146
 
    {
147
 
      if (!data[0] || !data[1])
148
 
        rc = gpg_error (GPG_ERR_BAD_MPI);
149
 
      else
150
 
        rc = gcry_sexp_build (&s_sig, NULL,
151
 
                              "(sig-val(dsa(r%m)(s%m)))", data[0], data[1]);
152
 
    }
153
 
  else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
154
 
    {
155
 
      if (!data[0] || !data[1])
156
 
        rc = gpg_error (GPG_ERR_BAD_MPI);
157
 
      else
158
 
        rc = gcry_sexp_build (&s_sig, NULL,
159
 
                              "(sig-val(elg(r%m)(s%m)))", data[0], data[1]);
160
 
    }
161
 
  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S)
162
 
    {
163
 
      if (!data[0])
164
 
        rc = gpg_error (GPG_ERR_BAD_MPI);
165
 
      else
166
 
        rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%m)))", data[0]);
167
 
    }
168
 
  else
169
 
    BUG ();
170
 
 
171
 
  if (!rc)
172
 
    rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
173
 
 
174
 
  gcry_sexp_release (s_sig);
175
 
  gcry_sexp_release (s_hash);
176
 
  gcry_sexp_release (s_pkey);
177
 
  return rc;
178
 
}
179
 
 
180
 
 
181
 
 
182
 
 
183
 
/****************
184
 
 * Emulate our old PK interface here - sometime in the future we might
185
 
 * change the internal design to directly fit to libgcrypt.
186
 
 */
187
 
int
188
 
pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, gcry_mpi_t * pkey)
189
 
{
190
 
  gcry_sexp_t s_ciph, s_data, s_pkey;
191
 
  int rc;
192
 
 
193
 
  /* make a sexp from pkey */
194
 
  if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
195
 
    {
196
 
      rc = gcry_sexp_build (&s_pkey, NULL,
197
 
                            "(public-key(elg(p%m)(g%m)(y%m)))",
198
 
                            pkey[0], pkey[1], pkey[2]);
199
 
    }
200
 
  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_E)
201
 
    {
202
 
      rc = gcry_sexp_build (&s_pkey, NULL,
203
 
                            "(public-key(rsa(n%m)(e%m)))",
204
 
                            pkey[0], pkey[1]);
205
 
    }
206
 
  else
207
 
    return GPG_ERR_PUBKEY_ALGO;
208
 
 
209
 
  if (rc)
210
 
    BUG ();
211
 
 
212
 
  /* put the data into a simple list */
213
 
  if (gcry_sexp_build (&s_data, NULL, "%m", data))
214
 
    BUG ();
215
 
 
216
 
  /* pass it to libgcrypt */
217
 
  rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
218
 
  gcry_sexp_release (s_data);
219
 
  gcry_sexp_release (s_pkey);
220
 
 
221
 
  if (rc)
222
 
    ;
223
 
  else
224
 
    { /* add better error handling or make gnupg use S-Exp directly */
225
 
      resarr[0] = mpi_from_sexp (s_ciph, "a");
226
 
      if (algo != GCRY_PK_RSA && algo != GCRY_PK_RSA_E)
227
 
        resarr[1] = mpi_from_sexp (s_ciph, "b");
228
 
    }
229
 
 
230
 
  gcry_sexp_release (s_ciph);
231
 
  return rc;
232
 
}
233
 
 
234
 
 
235
 
 
236
 
/****************
237
 
 * Emulate our old PK interface here - sometime in the future we might
238
 
 * change the internal design to directly fit to libgcrypt.
239
 
 */
240
 
int
241
 
pk_decrypt (int algo, gcry_mpi_t * result, gcry_mpi_t * data,
242
 
            gcry_mpi_t * skey)
243
 
{
244
 
  gcry_sexp_t s_skey, s_data, s_plain;
245
 
  int rc;
246
 
 
247
 
  *result = NULL;
248
 
  /* make a sexp from skey */
249
 
  if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
250
 
    {
251
 
      rc = gcry_sexp_build (&s_skey, NULL,
252
 
                            "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
253
 
                            skey[0], skey[1], skey[2], skey[3]);
254
 
    }
255
 
  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_E)
256
 
    {
257
 
      rc = gcry_sexp_build (&s_skey, NULL,
258
 
                            "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
259
 
                            skey[0], skey[1], skey[2], skey[3], skey[4],
260
 
                            skey[5]);
261
 
    }
262
 
  else
263
 
    return GPG_ERR_PUBKEY_ALGO;
264
 
 
265
 
  if (rc)
266
 
    BUG ();
267
 
 
268
 
  /* put data into a S-Exp s_data */
269
 
  if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
270
 
    {
271
 
      if (!data[0] || !data[1])
272
 
        rc = gpg_error (GPG_ERR_BAD_MPI);
273
 
      else
274
 
        rc = gcry_sexp_build (&s_data, NULL,
275
 
                              "(enc-val(elg(a%m)(b%m)))", data[0], data[1]);
276
 
    }
277
 
  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_E)
278
 
    {
279
 
      if (!data[0])
280
 
        rc = gpg_error (GPG_ERR_BAD_MPI);
281
 
      else
282
 
        rc = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", data[0]);
283
 
    }
284
 
  else
285
 
    BUG ();
286
 
 
287
 
  if (rc)
288
 
    BUG ();
289
 
 
290
 
  rc = gcry_pk_decrypt (&s_plain, s_data, s_skey);
291
 
  gcry_sexp_release (s_skey);
292
 
  gcry_sexp_release (s_data);
293
 
  if (rc)
294
 
    return rc;
295
 
 
296
 
  *result = gcry_sexp_nth_mpi (s_plain, 0, 0);
297
 
  gcry_sexp_release (s_plain);
298
 
  if (!*result)
299
 
    return -1;                  /* oops */
300
 
 
301
 
  return 0;
302
 
}
303
 
 
304
 
 
305
 
/* Check whether SKEY is a suitable secret key. */
306
 
int
307
 
pk_check_secret_key (int algo, gcry_mpi_t *skey)
308
 
{
309
 
  gcry_sexp_t s_skey;
310
 
  int rc;
311
 
 
312
 
  if (algo == GCRY_PK_DSA)
313
 
    {
314
 
      rc = gcry_sexp_build (&s_skey, NULL,
315
 
                            "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
316
 
                            skey[0], skey[1], skey[2], skey[3], skey[4]);
317
 
    }
318
 
  else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
319
 
    {
320
 
      rc = gcry_sexp_build (&s_skey, NULL,
321
 
                            "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
322
 
                            skey[0], skey[1], skey[2], skey[3]);
323
 
    }
324
 
  else if (algo == GCRY_PK_RSA
325
 
           || algo == GCRY_PK_RSA_S || algo == GCRY_PK_RSA_E)
326
 
    {
327
 
      rc = gcry_sexp_build (&s_skey, NULL,
328
 
                            "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
329
 
                            skey[0], skey[1], skey[2], skey[3], skey[4],
330
 
                            skey[5]);
331
 
    }
332
 
  else
333
 
    return GPG_ERR_PUBKEY_ALGO;
334
 
 
335
 
  if (!rc)
336
 
    {
337
 
      rc = gcry_pk_testkey (s_skey);
338
 
      gcry_sexp_release (s_skey);
339
 
    }
340
 
  return rc;
341
 
}