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/>.
33 mpi_from_sexp (gcry_sexp_t sexp
, const char * item
)
38 list
= gcry_sexp_find_token (sexp
, item
, 0);
40 data
= gcry_sexp_nth_mpi (list
, 1, 0);
42 gcry_sexp_release (list
);
48 * Emulate our old PK interface here - sometime in the future we might
49 * change the internal design to directly fit to libgcrypt.
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
;
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],
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]);
78 return GPG_ERR_PUBKEY_ALGO
;
83 /* put hash into a S-Exp s_hash */
84 if (gcry_sexp_build (&s_hash
, NULL
, "%m", hash
))
87 rc
= gcry_pk_sign (&s_sig
, s_hash
, s_skey
);
88 gcry_sexp_release (s_hash
);
89 gcry_sexp_release (s_skey
);
93 else if (algo
== GCRY_PK_RSA
)
94 data
[0] = mpi_from_sexp (s_sig
, "s");
97 data
[0] = mpi_from_sexp (s_sig
, "r");
98 data
[1] = mpi_from_sexp (s_sig
, "s");
101 gcry_sexp_release (s_sig
);
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
;
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]);
134 return GPG_ERR_PUBKEY_ALGO
;
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. */
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]);
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
);
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
;
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)))",
207 return GPG_ERR_PUBKEY_ALGO
;
212 /* put the data into a simple list */
213 if (gcry_sexp_build (&s_data
, NULL
, "%m", data
))
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
);
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
);
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
,
244 gcry_sexp_t s_skey
, s_data
, s_plain
;
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],
263 return GPG_ERR_PUBKEY_ALGO
;
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
);
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
)
280 rc
= gpg_error (GPG_ERR_BAD_MPI
);
282 rc
= gcry_sexp_build (&s_data
, NULL
, "(enc-val(rsa(a%m)))", data
[0]);
290 rc
= gcry_pk_decrypt (&s_plain
, s_data
, s_skey
);
291 gcry_sexp_release (s_skey
);
292 gcry_sexp_release (s_data
);
296 *result
= gcry_sexp_nth_mpi (s_plain
, 0, 0);
297 gcry_sexp_release (s_plain
);
299 return -1; /* oops */
305 /* Check whether SKEY is a suitable secret key. */
307 pk_check_secret_key (int algo
, gcry_mpi_t
*skey
)
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],
332 return GPG_ERR_PUBKEY_ALGO
;
336 rc
= gcry_pk_testkey (s_skey
);
337 gcry_sexp_release (s_skey
);