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
;
139 /* put hash into a S-Exp s_hash */
140 if (gcry_sexp_build (&s_hash
, NULL
, "%m", hash
))
143 /* put data into a S-Exp s_sig */
144 if (algo
== GCRY_PK_DSA
)
146 if (!data
[0] || !data
[1])
147 rc
= gpg_error (GPG_ERR_BAD_MPI
);
149 rc
= gcry_sexp_build (&s_sig
, NULL
,
150 "(sig-val(dsa(r%m)(s%m)))", data
[0], data
[1]);
152 else if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
154 if (!data
[0] || !data
[1])
155 rc
= gpg_error (GPG_ERR_BAD_MPI
);
157 rc
= gcry_sexp_build (&s_sig
, NULL
,
158 "(sig-val(elg(r%m)(s%m)))", data
[0], data
[1]);
160 else if (algo
== GCRY_PK_RSA
)
163 rc
= gpg_error (GPG_ERR_BAD_MPI
);
165 rc
= gcry_sexp_build (&s_sig
, NULL
, "(sig-val(rsa(s%m)))", data
[0]);
174 rc
= gcry_pk_verify (s_sig
, s_hash
, s_pkey
);
175 gcry_sexp_release (s_sig
);
176 gcry_sexp_release (s_hash
);
177 gcry_sexp_release (s_pkey
);
185 * Emulate our old PK interface here - sometime in the future we might
186 * change the internal design to directly fit to libgcrypt.
189 pk_encrypt (int algo
, gcry_mpi_t
* resarr
, gcry_mpi_t data
, gcry_mpi_t
* pkey
)
191 gcry_sexp_t s_ciph
, s_data
, s_pkey
;
194 /* make a sexp from pkey */
195 if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
197 rc
= gcry_sexp_build (&s_pkey
, NULL
,
198 "(public-key(elg(p%m)(g%m)(y%m)))",
199 pkey
[0], pkey
[1], pkey
[2]);
201 else if (algo
== GCRY_PK_RSA
)
203 rc
= gcry_sexp_build (&s_pkey
, NULL
,
204 "(public-key(rsa(n%m)(e%m)))",
208 return GPG_ERR_PUBKEY_ALGO
;
213 /* put the data into a simple list */
214 if (gcry_sexp_build (&s_data
, NULL
, "%m", data
))
217 /* pass it to libgcrypt */
218 rc
= gcry_pk_encrypt (&s_ciph
, s_data
, s_pkey
);
219 gcry_sexp_release (s_data
);
220 gcry_sexp_release (s_pkey
);
225 { /* add better error handling or make gnupg use S-Exp directly */
226 resarr
[0] = mpi_from_sexp (s_ciph
, "a");
227 if (algo
!= GCRY_PK_RSA
)
228 resarr
[1] = mpi_from_sexp (s_ciph
, "b");
231 gcry_sexp_release (s_ciph
);
238 * Emulate our old PK interface here - sometime in the future we might
239 * change the internal design to directly fit to libgcrypt.
242 pk_decrypt (int algo
, gcry_mpi_t
* result
, gcry_mpi_t
* data
,
245 gcry_sexp_t s_skey
, s_data
, s_plain
;
249 /* make a sexp from skey */
250 if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
252 rc
= gcry_sexp_build (&s_skey
, NULL
,
253 "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
254 skey
[0], skey
[1], skey
[2], skey
[3]);
256 else if (algo
== GCRY_PK_RSA
)
258 rc
= gcry_sexp_build (&s_skey
, NULL
,
259 "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
260 skey
[0], skey
[1], skey
[2], skey
[3], skey
[4],
264 return GPG_ERR_PUBKEY_ALGO
;
269 /* put data into a S-Exp s_data */
270 if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
272 if (!data
[0] || !data
[1])
273 rc
= gpg_error (GPG_ERR_BAD_MPI
);
275 rc
= gcry_sexp_build (&s_data
, NULL
,
276 "(enc-val(elg(a%m)(b%m)))", data
[0], data
[1]);
278 else if (algo
== GCRY_PK_RSA
)
281 rc
= gpg_error (GPG_ERR_BAD_MPI
);
283 rc
= gcry_sexp_build (&s_data
, NULL
, "(enc-val(rsa(a%m)))", data
[0]);
291 rc
= gcry_pk_decrypt (&s_plain
, s_data
, s_skey
);
292 gcry_sexp_release (s_skey
);
293 gcry_sexp_release (s_data
);
297 *result
= gcry_sexp_nth_mpi (s_plain
, 0, 0);
298 gcry_sexp_release (s_plain
);
300 return -1; /* oops */
306 /* Check whether SKEY is a suitable secret key. */
308 pk_check_secret_key (int algo
, gcry_mpi_t
*skey
)
313 if (algo
== GCRY_PK_DSA
)
315 rc
= gcry_sexp_build (&s_skey
, NULL
,
316 "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
317 skey
[0], skey
[1], skey
[2], skey
[3], skey
[4]);
319 else if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
321 rc
= gcry_sexp_build (&s_skey
, NULL
,
322 "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
323 skey
[0], skey
[1], skey
[2], skey
[3]);
325 else if (algo
== GCRY_PK_RSA
)
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],
333 return GPG_ERR_PUBKEY_ALGO
;
337 rc
= gcry_pk_testkey (s_skey
);
338 gcry_sexp_release (s_skey
);