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 2 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
34 mpi_from_sexp (gcry_sexp_t sexp
, const char * item
)
39 list
= gcry_sexp_find_token (sexp
, item
, 0);
41 data
= gcry_sexp_nth_mpi (list
, 1, 0);
43 gcry_sexp_release (list
);
49 * Emulate our old PK interface here - sometime in the future we might
50 * change the internal design to directly fit to libgcrypt.
53 pk_sign (int algo
, gcry_mpi_t
* data
, gcry_mpi_t hash
, gcry_mpi_t
* skey
)
55 gcry_sexp_t s_sig
, s_hash
, s_skey
;
58 /* make a sexp from skey */
59 if (algo
== GCRY_PK_DSA
)
61 rc
= gcry_sexp_build (&s_skey
, NULL
,
62 "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
63 skey
[0], skey
[1], skey
[2], skey
[3], skey
[4]);
65 else if (algo
== GCRY_PK_RSA
)
67 rc
= gcry_sexp_build (&s_skey
, NULL
,
68 "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
69 skey
[0], skey
[1], skey
[2], skey
[3], skey
[4],
72 else if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
74 rc
= gcry_sexp_build (&s_skey
, NULL
,
75 "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
76 skey
[0], skey
[1], skey
[2], skey
[3]);
79 return GPG_ERR_PUBKEY_ALGO
;
84 /* put hash into a S-Exp s_hash */
85 if (gcry_sexp_build (&s_hash
, NULL
, "%m", hash
))
88 rc
= gcry_pk_sign (&s_sig
, s_hash
, s_skey
);
89 gcry_sexp_release (s_hash
);
90 gcry_sexp_release (s_skey
);
94 else if (algo
== GCRY_PK_RSA
)
95 data
[0] = mpi_from_sexp (s_sig
, "s");
98 data
[0] = mpi_from_sexp (s_sig
, "r");
99 data
[1] = mpi_from_sexp (s_sig
, "s");
102 gcry_sexp_release (s_sig
);
107 * Emulate our old PK interface here - sometime in the future we might
108 * change the internal design to directly fit to libgcrypt.
111 pk_verify (int algo
, gcry_mpi_t hash
, gcry_mpi_t
* data
, gcry_mpi_t
* pkey
)
113 gcry_sexp_t s_sig
, s_hash
, s_pkey
;
116 /* make a sexp from pkey */
117 if (algo
== GCRY_PK_DSA
)
119 rc
= gcry_sexp_build (&s_pkey
, NULL
,
120 "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
121 pkey
[0], pkey
[1], pkey
[2], pkey
[3]);
123 else if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
125 rc
= gcry_sexp_build (&s_pkey
, NULL
,
126 "(public-key(elg(p%m)(g%m)(y%m)))",
127 pkey
[0], pkey
[1], pkey
[2]);
129 else if (algo
== GCRY_PK_RSA
)
131 rc
= gcry_sexp_build (&s_pkey
, NULL
,
132 "(public-key(rsa(n%m)(e%m)))", pkey
[0], pkey
[1]);
135 return GPG_ERR_PUBKEY_ALGO
;
140 /* put hash into a S-Exp s_hash */
141 if (gcry_sexp_build (&s_hash
, NULL
, "%m", hash
))
144 /* put data into a S-Exp s_sig */
145 if (algo
== GCRY_PK_DSA
)
147 if (!data
[0] || !data
[1])
148 rc
= gpg_error (GPG_ERR_BAD_MPI
);
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
);
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
)
164 rc
= gpg_error (GPG_ERR_BAD_MPI
);
166 rc
= gcry_sexp_build (&s_sig
, NULL
, "(sig-val(rsa(s%m)))", data
[0]);
175 rc
= gcry_pk_verify (s_sig
, s_hash
, s_pkey
);
176 gcry_sexp_release (s_sig
);
177 gcry_sexp_release (s_hash
);
178 gcry_sexp_release (s_pkey
);
186 * Emulate our old PK interface here - sometime in the future we might
187 * change the internal design to directly fit to libgcrypt.
190 pk_encrypt (int algo
, gcry_mpi_t
* resarr
, gcry_mpi_t data
, gcry_mpi_t
* pkey
)
192 gcry_sexp_t s_ciph
, s_data
, s_pkey
;
195 /* make a sexp from pkey */
196 if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
198 rc
= gcry_sexp_build (&s_pkey
, NULL
,
199 "(public-key(elg(p%m)(g%m)(y%m)))",
200 pkey
[0], pkey
[1], pkey
[2]);
202 else if (algo
== GCRY_PK_RSA
)
204 rc
= gcry_sexp_build (&s_pkey
, NULL
,
205 "(public-key(rsa(n%m)(e%m)))",
209 return GPG_ERR_PUBKEY_ALGO
;
214 /* put the data into a simple list */
215 if (gcry_sexp_build (&s_data
, NULL
, "%m", data
))
218 /* pass it to libgcrypt */
219 rc
= gcry_pk_encrypt (&s_ciph
, s_data
, s_pkey
);
220 gcry_sexp_release (s_data
);
221 gcry_sexp_release (s_pkey
);
226 { /* add better error handling or make gnupg use S-Exp directly */
227 resarr
[0] = mpi_from_sexp (s_ciph
, "a");
228 if (algo
!= GCRY_PK_RSA
)
229 resarr
[1] = mpi_from_sexp (s_ciph
, "b");
232 gcry_sexp_release (s_ciph
);
239 * Emulate our old PK interface here - sometime in the future we might
240 * change the internal design to directly fit to libgcrypt.
243 pk_decrypt (int algo
, gcry_mpi_t
* result
, gcry_mpi_t
* data
,
246 gcry_sexp_t s_skey
, s_data
, s_plain
;
250 /* make a sexp from skey */
251 if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
253 rc
= gcry_sexp_build (&s_skey
, NULL
,
254 "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
255 skey
[0], skey
[1], skey
[2], skey
[3]);
257 else if (algo
== GCRY_PK_RSA
)
259 rc
= gcry_sexp_build (&s_skey
, NULL
,
260 "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
261 skey
[0], skey
[1], skey
[2], skey
[3], skey
[4],
265 return GPG_ERR_PUBKEY_ALGO
;
270 /* put data into a S-Exp s_data */
271 if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
273 if (!data
[0] || !data
[1])
274 rc
= gpg_error (GPG_ERR_BAD_MPI
);
276 rc
= gcry_sexp_build (&s_data
, NULL
,
277 "(enc-val(elg(a%m)(b%m)))", data
[0], data
[1]);
279 else if (algo
== GCRY_PK_RSA
)
282 rc
= gpg_error (GPG_ERR_BAD_MPI
);
284 rc
= gcry_sexp_build (&s_data
, NULL
, "(enc-val(rsa(a%m)))", data
[0]);
292 rc
= gcry_pk_decrypt (&s_plain
, s_data
, s_skey
);
293 gcry_sexp_release (s_skey
);
294 gcry_sexp_release (s_data
);
298 *result
= gcry_sexp_nth_mpi (s_plain
, 0, 0);
299 gcry_sexp_release (s_plain
);
301 return -1; /* oops */
307 /* Check whether SKEY is a suitable secret key. */
309 pk_check_secret_key (int algo
, gcry_mpi_t
*skey
)
314 if (algo
== GCRY_PK_DSA
)
316 rc
= gcry_sexp_build (&s_skey
, NULL
,
317 "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
318 skey
[0], skey
[1], skey
[2], skey
[3], skey
[4]);
320 else if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
322 rc
= gcry_sexp_build (&s_skey
, NULL
,
323 "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
324 skey
[0], skey
[1], skey
[2], skey
[3]);
326 else if (algo
== GCRY_PK_RSA
)
328 rc
= gcry_sexp_build (&s_skey
, NULL
,
329 "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
330 skey
[0], skey
[1], skey
[2], skey
[3], skey
[4],
334 return GPG_ERR_PUBKEY_ALGO
;
338 rc
= gcry_pk_testkey (s_skey
);
339 gcry_sexp_release (s_skey
);