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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
35 mpi_from_sexp (gcry_sexp_t sexp
, const char * item
)
40 list
= gcry_sexp_find_token (sexp
, item
, 0);
42 data
= gcry_sexp_nth_mpi (list
, 1, 0);
44 gcry_sexp_release (list
);
50 * Emulate our old PK interface here - sometime in the future we might
51 * change the internal design to directly fit to libgcrypt.
54 pk_sign (int algo
, gcry_mpi_t
* data
, gcry_mpi_t hash
, gcry_mpi_t
* skey
)
56 gcry_sexp_t s_sig
, s_hash
, s_skey
;
59 /* make a sexp from skey */
60 if (algo
== GCRY_PK_DSA
)
62 rc
= gcry_sexp_build (&s_skey
, NULL
,
63 "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
64 skey
[0], skey
[1], skey
[2], skey
[3], skey
[4]);
66 else if (algo
== GCRY_PK_RSA
)
68 rc
= gcry_sexp_build (&s_skey
, NULL
,
69 "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
70 skey
[0], skey
[1], skey
[2], skey
[3], skey
[4],
73 else if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
75 rc
= gcry_sexp_build (&s_skey
, NULL
,
76 "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
77 skey
[0], skey
[1], skey
[2], skey
[3]);
80 return GPG_ERR_PUBKEY_ALGO
;
85 /* put hash into a S-Exp s_hash */
86 if (gcry_sexp_build (&s_hash
, NULL
, "%m", hash
))
89 rc
= gcry_pk_sign (&s_sig
, s_hash
, s_skey
);
90 gcry_sexp_release (s_hash
);
91 gcry_sexp_release (s_skey
);
95 else if (algo
== GCRY_PK_RSA
)
96 data
[0] = mpi_from_sexp (s_sig
, "s");
99 data
[0] = mpi_from_sexp (s_sig
, "r");
100 data
[1] = mpi_from_sexp (s_sig
, "s");
103 gcry_sexp_release (s_sig
);
108 * Emulate our old PK interface here - sometime in the future we might
109 * change the internal design to directly fit to libgcrypt.
112 pk_verify (int algo
, gcry_mpi_t hash
, gcry_mpi_t
* data
, gcry_mpi_t
* pkey
)
114 gcry_sexp_t s_sig
, s_hash
, s_pkey
;
117 /* make a sexp from pkey */
118 if (algo
== GCRY_PK_DSA
)
120 rc
= gcry_sexp_build (&s_pkey
, NULL
,
121 "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
122 pkey
[0], pkey
[1], pkey
[2], pkey
[3]);
124 else if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
126 rc
= gcry_sexp_build (&s_pkey
, NULL
,
127 "(public-key(elg(p%m)(g%m)(y%m)))",
128 pkey
[0], pkey
[1], pkey
[2]);
130 else if (algo
== GCRY_PK_RSA
)
132 rc
= gcry_sexp_build (&s_pkey
, NULL
,
133 "(public-key(rsa(n%m)(e%m)))", pkey
[0], pkey
[1]);
136 return GPG_ERR_PUBKEY_ALGO
;
141 /* put hash into a S-Exp s_hash */
142 if (gcry_sexp_build (&s_hash
, NULL
, "%m", hash
))
145 /* put data into a S-Exp s_sig */
146 if (algo
== GCRY_PK_DSA
)
148 if (!data
[0] || !data
[1])
149 rc
= gpg_error (GPG_ERR_BAD_MPI
);
151 rc
= gcry_sexp_build (&s_sig
, NULL
,
152 "(sig-val(dsa(r%m)(s%m)))", data
[0], data
[1]);
154 else if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
156 if (!data
[0] || !data
[1])
157 rc
= gpg_error (GPG_ERR_BAD_MPI
);
159 rc
= gcry_sexp_build (&s_sig
, NULL
,
160 "(sig-val(elg(r%m)(s%m)))", data
[0], data
[1]);
162 else if (algo
== GCRY_PK_RSA
)
165 rc
= gpg_error (GPG_ERR_BAD_MPI
);
167 rc
= gcry_sexp_build (&s_sig
, NULL
, "(sig-val(rsa(s%m)))", data
[0]);
176 rc
= gcry_pk_verify (s_sig
, s_hash
, s_pkey
);
177 gcry_sexp_release (s_sig
);
178 gcry_sexp_release (s_hash
);
179 gcry_sexp_release (s_pkey
);
187 * Emulate our old PK interface here - sometime in the future we might
188 * change the internal design to directly fit to libgcrypt.
191 pk_encrypt (int algo
, gcry_mpi_t
* resarr
, gcry_mpi_t data
, gcry_mpi_t
* pkey
)
193 gcry_sexp_t s_ciph
, s_data
, s_pkey
;
196 /* make a sexp from pkey */
197 if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
199 rc
= gcry_sexp_build (&s_pkey
, NULL
,
200 "(public-key(elg(p%m)(g%m)(y%m)))",
201 pkey
[0], pkey
[1], pkey
[2]);
203 else if (algo
== GCRY_PK_RSA
)
205 rc
= gcry_sexp_build (&s_pkey
, NULL
,
206 "(public-key(rsa(n%m)(e%m)))",
210 return GPG_ERR_PUBKEY_ALGO
;
215 /* put the data into a simple list */
216 if (gcry_sexp_build (&s_data
, NULL
, "%m", data
))
219 /* pass it to libgcrypt */
220 rc
= gcry_pk_encrypt (&s_ciph
, s_data
, s_pkey
);
221 gcry_sexp_release (s_data
);
222 gcry_sexp_release (s_pkey
);
227 { /* add better error handling or make gnupg use S-Exp directly */
228 resarr
[0] = mpi_from_sexp (s_ciph
, "a");
229 if (algo
!= GCRY_PK_RSA
)
230 resarr
[1] = mpi_from_sexp (s_ciph
, "b");
233 gcry_sexp_release (s_ciph
);
240 * Emulate our old PK interface here - sometime in the future we might
241 * change the internal design to directly fit to libgcrypt.
244 pk_decrypt (int algo
, gcry_mpi_t
* result
, gcry_mpi_t
* data
,
247 gcry_sexp_t s_skey
, s_data
, s_plain
;
251 /* make a sexp from skey */
252 if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
254 rc
= gcry_sexp_build (&s_skey
, NULL
,
255 "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
256 skey
[0], skey
[1], skey
[2], skey
[3]);
258 else if (algo
== GCRY_PK_RSA
)
260 rc
= gcry_sexp_build (&s_skey
, NULL
,
261 "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
262 skey
[0], skey
[1], skey
[2], skey
[3], skey
[4],
266 return GPG_ERR_PUBKEY_ALGO
;
271 /* put data into a S-Exp s_data */
272 if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
274 if (!data
[0] || !data
[1])
275 rc
= gpg_error (GPG_ERR_BAD_MPI
);
277 rc
= gcry_sexp_build (&s_data
, NULL
,
278 "(enc-val(elg(a%m)(b%m)))", data
[0], data
[1]);
280 else if (algo
== GCRY_PK_RSA
)
283 rc
= gpg_error (GPG_ERR_BAD_MPI
);
285 rc
= gcry_sexp_build (&s_data
, NULL
, "(enc-val(rsa(a%m)))", data
[0]);
293 rc
= gcry_pk_decrypt (&s_plain
, s_data
, s_skey
);
294 gcry_sexp_release (s_skey
);
295 gcry_sexp_release (s_data
);
299 *result
= gcry_sexp_nth_mpi (s_plain
, 0, 0);
300 gcry_sexp_release (s_plain
);
302 return -1; /* oops */
308 /* Check whether SKEY is a suitable secret key. */
310 pk_check_secret_key (int algo
, gcry_mpi_t
*skey
)
315 if (algo
== GCRY_PK_DSA
)
317 rc
= gcry_sexp_build (&s_skey
, NULL
,
318 "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
319 skey
[0], skey
[1], skey
[2], skey
[3], skey
[4]);
321 else if (algo
== GCRY_PK_ELG
|| algo
== GCRY_PK_ELG_E
)
323 rc
= gcry_sexp_build (&s_skey
, NULL
,
324 "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
325 skey
[0], skey
[1], skey
[2], skey
[3]);
327 else if (algo
== GCRY_PK_RSA
)
329 rc
= gcry_sexp_build (&s_skey
, NULL
,
330 "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
331 skey
[0], skey
[1], skey
[2], skey
[3], skey
[4],
335 return GPG_ERR_PUBKEY_ALGO
;
339 rc
= gcry_pk_testkey (s_skey
);
340 gcry_sexp_release (s_skey
);