1 /* pksign.c - public key signing (well, actually using a secret key)
2 * Copyright (C) 2001, 2002, 2003, 2004 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
35 do_encode_md (const byte
* md
, size_t mdlen
, int algo
, gcry_sexp_t
* r_hash
)
42 s
= gcry_md_algo_name (algo
);
43 if (s
&& strlen (s
) < 16)
45 for (i
=0; i
< strlen (s
); i
++)
46 tmp
[i
] = tolower (s
[i
]);
49 rc
= gcry_sexp_build (&hash
, NULL
,
50 "(data (flags pkcs1) (hash %s %b))",
58 /* SIGN whatever information we have accumulated in CTRL and write it
61 agent_pksign (CTRL ctrl
, const char *desc_text
, FILE *outfp
, int ignore_cache
)
63 gcry_sexp_t s_skey
= NULL
, s_hash
= NULL
, s_sig
= NULL
;
64 unsigned char *shadow_info
= NULL
;
69 if (!ctrl
->have_keygrip
)
70 return gpg_error (GPG_ERR_NO_SECKEY
);
72 rc
= agent_key_from_file (ctrl
, desc_text
, ctrl
->keygrip
,
73 &shadow_info
, ignore_cache
, &s_skey
);
76 log_error ("failed to read the secret key\n");
81 { /* divert operation to the smartcard */
82 unsigned char *sigbuf
;
84 rc
= divert_pksign (ctrl
,
86 ctrl
->digest
.valuelen
,
88 shadow_info
, &sigbuf
);
91 log_error ("smartcard signing failed: %s\n", gpg_strerror (rc
));
94 len
= gcry_sexp_canon_len (sigbuf
, 0, NULL
, NULL
);
99 { /* no smartcard, but a private key */
101 /* put the hash into a sexp */
102 rc
= do_encode_md (ctrl
->digest
.value
,
103 ctrl
->digest
.valuelen
,
111 log_debug ("skey: ");
112 gcry_sexp_dump (s_skey
);
116 rc
= gcry_pk_sign (&s_sig
, s_hash
, s_skey
);
119 log_error ("signing failed: %s\n", gpg_strerror (rc
));
125 log_debug ("result: ");
126 gcry_sexp_dump (s_sig
);
129 len
= gcry_sexp_sprint (s_sig
, GCRYSEXP_FMT_CANON
, NULL
, 0);
132 len
= gcry_sexp_sprint (s_sig
, GCRYSEXP_FMT_CANON
, buf
, len
);
136 /* FIXME: we must make sure that no buffering takes place or we are
137 in full control of the buffer memory (easy to do) - should go
139 fwrite (buf
, 1, len
, outfp
);
142 gcry_sexp_release (s_skey
);
143 gcry_sexp_release (s_hash
);
144 gcry_sexp_release (s_sig
);