Updated the german translation
[gnupg.git] / g10 / pkglue.c
blob90f8f248b6e5c1c3dff693e51b6d004c512d3dbf
1 /* pkglue.c - public key operations glue code
2 * Copyright (C) 2000, 2003 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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/>.
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <assert.h>
27 #include "gpg.h"
28 #include "util.h"
29 #include "pkglue.h"
32 static gcry_mpi_t
33 mpi_from_sexp (gcry_sexp_t sexp, const char * item)
35 gcry_sexp_t list;
36 gcry_mpi_t data;
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;
47 /****************
48 * Emulate our old PK interface here - sometime in the future we might
49 * change the internal design to directly fit to libgcrypt.
51 int
52 pk_sign (int algo, gcry_mpi_t * data, gcry_mpi_t hash, gcry_mpi_t * skey)
54 gcry_sexp_t s_sig, s_hash, s_skey;
55 int rc;
57 /* make a sexp from skey */
58 if (algo == GCRY_PK_DSA)
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]);
64 else if (algo == GCRY_PK_RSA)
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]);
71 else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
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]);
77 else
78 return GPG_ERR_PUBKEY_ALGO;
80 if (rc)
81 BUG ();
83 /* put hash into a S-Exp s_hash */
84 if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
85 BUG ();
87 rc = gcry_pk_sign (&s_sig, s_hash, s_skey);
88 gcry_sexp_release (s_hash);
89 gcry_sexp_release (s_skey);
91 if (rc)
93 else if (algo == GCRY_PK_RSA)
94 data[0] = mpi_from_sexp (s_sig, "s");
95 else
97 data[0] = mpi_from_sexp (s_sig, "r");
98 data[1] = mpi_from_sexp (s_sig, "s");
101 gcry_sexp_release (s_sig);
102 return rc;
105 /****************
106 * Emulate our old PK interface here - sometime in the future we might
107 * change the internal design to directly fit to libgcrypt.
110 pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey)
112 gcry_sexp_t s_sig, s_hash, s_pkey;
113 int rc;
115 /* make a sexp from pkey */
116 if (algo == GCRY_PK_DSA)
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]);
122 else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
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]);
128 else if (algo == GCRY_PK_RSA)
130 rc = gcry_sexp_build (&s_pkey, NULL,
131 "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]);
133 else
134 return GPG_ERR_PUBKEY_ALGO;
136 if (rc)
137 BUG (); /* gcry_sexp_build should never fail. */
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. */
143 /* Put data into a S-Exp s_sig. */
144 s_sig = NULL;
145 if (algo == GCRY_PK_DSA)
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]);
153 else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
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]);
161 else if (algo == GCRY_PK_RSA)
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]);
168 else
169 BUG ();
171 if (!rc)
172 rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
174 gcry_sexp_release (s_sig);
175 gcry_sexp_release (s_hash);
176 gcry_sexp_release (s_pkey);
177 return rc;
183 /****************
184 * Emulate our old PK interface here - sometime in the future we might
185 * change the internal design to directly fit to libgcrypt.
188 pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, gcry_mpi_t * pkey)
190 gcry_sexp_t s_ciph, s_data, s_pkey;
191 int rc;
193 /* make a sexp from pkey */
194 if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
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]);
200 else if (algo == GCRY_PK_RSA)
202 rc = gcry_sexp_build (&s_pkey, NULL,
203 "(public-key(rsa(n%m)(e%m)))",
204 pkey[0], pkey[1]);
206 else
207 return GPG_ERR_PUBKEY_ALGO;
209 if (rc)
210 BUG ();
212 /* put the data into a simple list */
213 if (gcry_sexp_build (&s_data, NULL, "%m", data))
214 BUG ();
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);
221 if (rc)
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)
227 resarr[1] = mpi_from_sexp (s_ciph, "b");
230 gcry_sexp_release (s_ciph);
231 return rc;
236 /****************
237 * Emulate our old PK interface here - sometime in the future we might
238 * change the internal design to directly fit to libgcrypt.
241 pk_decrypt (int algo, gcry_mpi_t * result, gcry_mpi_t * data,
242 gcry_mpi_t * skey)
244 gcry_sexp_t s_skey, s_data, s_plain;
245 int rc;
247 *result = NULL;
248 /* make a sexp from skey */
249 if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
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]);
255 else if (algo == GCRY_PK_RSA)
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]);
262 else
263 return GPG_ERR_PUBKEY_ALGO;
265 if (rc)
266 BUG ();
268 /* put data into a S-Exp s_data */
269 if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
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]);
277 else if (algo == GCRY_PK_RSA)
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]);
284 else
285 BUG ();
287 if (rc)
288 BUG ();
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;
296 *result = gcry_sexp_nth_mpi (s_plain, 0, 0);
297 gcry_sexp_release (s_plain);
298 if (!*result)
299 return -1; /* oops */
301 return 0;
305 /* Check whether SKEY is a suitable secret key. */
307 pk_check_secret_key (int algo, gcry_mpi_t *skey)
309 gcry_sexp_t s_skey;
310 int rc;
312 if (algo == GCRY_PK_DSA)
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]);
318 else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
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]);
324 else if (algo == GCRY_PK_RSA)
326 rc = gcry_sexp_build (&s_skey, NULL,
327 "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
328 skey[0], skey[1], skey[2], skey[3], skey[4],
329 skey[5]);
331 else
332 return GPG_ERR_PUBKEY_ALGO;
334 if (!rc)
336 rc = gcry_pk_testkey (s_skey);
337 gcry_sexp_release (s_skey);
339 return rc;