1 /* certcheck.c - check one certificate
2 * Copyright (C) 2001, 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
39 do_encode_md (gcry_md_hd_t md
, int algo
, int pkalgo
, unsigned int nbits
,
45 if (pkalgo
== GCRY_PK_DSA
)
47 nframe
= gcry_md_get_algo_dlen (algo
);
50 log_error (_("DSA requires the use of a 160 bit hash algorithm\n"));
51 return gpg_error (GPG_ERR_INTERNAL
);
53 frame
= xtrymalloc (nframe
);
55 return OUT_OF_CORE (errno
);
56 memcpy (frame
, gcry_md_read (md
, algo
), nframe
);
62 unsigned char asn
[100];
66 nframe
= (nbits
+7) / 8;
69 if (gcry_md_algo_info (algo
, GCRYCTL_GET_ASNOID
, asn
, &asnlen
))
71 log_error ("no object identifier for algo %d\n", algo
);
72 return gpg_error (GPG_ERR_INTERNAL
);
75 len
= gcry_md_get_algo_dlen (algo
);
77 if ( len
+ asnlen
+ 4 > nframe
)
79 log_error ("can't encode a %d bit MD into a %d bits frame\n",
80 (int)(len
*8), (int)nbits
);
81 return gpg_error (GPG_ERR_INTERNAL
);
84 /* We encode the MD in this way:
86 * 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
88 * PAD consists of FF bytes.
90 frame
= xtrymalloc (nframe
);
92 return OUT_OF_CORE (errno
);
95 frame
[n
++] = 1; /* block type */
96 i
= nframe
- len
- asnlen
-3 ;
98 memset ( frame
+n
, 0xff, i
); n
+= i
;
100 memcpy ( frame
+n
, asn
, asnlen
); n
+= asnlen
;
101 memcpy ( frame
+n
, gcry_md_read(md
, algo
), len
); n
+= len
;
102 assert ( n
== nframe
);
107 log_debug ("encoded hash:");
108 for (j
=0; j
< nframe
; j
++)
109 log_printf (" %02X", frame
[j
]);
113 gcry_mpi_scan (r_val
, GCRYMPI_FMT_USG
, frame
, n
, &nframe
);
118 /* Return the public key algorithm id from the S-expression PKEY.
119 FIXME: libgcrypt should provide such a function. Note that this
120 implementation uses the names as used by libksba. */
122 pk_algo_from_sexp (gcry_sexp_t pkey
)
129 l1
= gcry_sexp_find_token (pkey
, "public-key", 0);
131 return 0; /* Not found. */
132 l2
= gcry_sexp_cadr (l1
);
133 gcry_sexp_release (l1
);
135 name
= gcry_sexp_nth_data (l2
, 0, &n
);
137 algo
= 0; /* Not found. */
138 else if (n
==3 && !memcmp (name
, "rsa", 3))
140 else if (n
==3 && !memcmp (name
, "dsa", 3))
142 else if (n
==13 && !memcmp (name
, "ambiguous-rsa", 13))
146 gcry_sexp_release (l2
);
152 Check the signature on CERT using the ISSUER-CERT. This function
153 does only test the cryptographic signature and nothing else. It is
154 assumed that the ISSUER_CERT is valid. */
156 gpgsm_check_cert_sig (ksba_cert_t issuer_cert
, ksba_cert_t cert
)
164 gcry_sexp_t s_sig
, s_hash
, s_pkey
;
166 algo
= gcry_md_map_name ( (algoid
=ksba_cert_get_digest_algo (cert
)));
169 log_error ("unknown hash algorithm `%s'\n", algoid
? algoid
:"?");
170 return gpg_error (GPG_ERR_GENERAL
);
172 rc
= gcry_md_open (&md
, algo
, 0);
175 log_error ("md_open failed: %s\n", gpg_strerror (rc
));
179 gcry_md_start_debug (md
, "hash.cert");
181 rc
= ksba_cert_hash (cert
, 1, HASH_FNC
, md
);
184 log_error ("ksba_cert_hash failed: %s\n", gpg_strerror (rc
));
190 p
= ksba_cert_get_sig_val (cert
);
191 n
= gcry_sexp_canon_len (p
, 0, NULL
, NULL
);
194 log_error ("libksba did not return a proper S-Exp\n");
197 return gpg_error (GPG_ERR_BUG
);
202 log_debug ("signature value:");
203 for (j
=0; j
< n
; j
++)
204 log_printf (" %02X", p
[j
]);
208 rc
= gcry_sexp_sscan ( &s_sig
, NULL
, p
, n
);
212 log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc
));
217 p
= ksba_cert_get_public_key (issuer_cert
);
218 n
= gcry_sexp_canon_len (p
, 0, NULL
, NULL
);
221 log_error ("libksba did not return a proper S-Exp\n");
224 gcry_sexp_release (s_sig
);
225 return gpg_error (GPG_ERR_BUG
);
227 rc
= gcry_sexp_sscan ( &s_pkey
, NULL
, p
, n
);
231 log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc
));
233 gcry_sexp_release (s_sig
);
237 rc
= do_encode_md (md
, algo
, pk_algo_from_sexp (s_pkey
),
238 gcry_pk_get_nbits (s_pkey
), &frame
);
242 gcry_sexp_release (s_sig
);
243 gcry_sexp_release (s_pkey
);
247 /* put hash into the S-Exp s_hash */
248 if ( gcry_sexp_build (&s_hash
, NULL
, "%m", frame
) )
250 gcry_mpi_release (frame
);
253 rc
= gcry_pk_verify (s_sig
, s_hash
, s_pkey
);
255 log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc
));
257 gcry_sexp_release (s_sig
);
258 gcry_sexp_release (s_hash
);
259 gcry_sexp_release (s_pkey
);
266 gpgsm_check_cms_signature (ksba_cert_t cert
, ksba_const_sexp_t sigval
,
267 gcry_md_hd_t md
, int algo
)
272 gcry_sexp_t s_sig
, s_hash
, s_pkey
;
275 n
= gcry_sexp_canon_len (sigval
, 0, NULL
, NULL
);
278 log_error ("libksba did not return a proper S-Exp\n");
279 return gpg_error (GPG_ERR_BUG
);
281 rc
= gcry_sexp_sscan (&s_sig
, NULL
, sigval
, n
);
284 log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc
));
288 p
= ksba_cert_get_public_key (cert
);
289 n
= gcry_sexp_canon_len (p
, 0, NULL
, NULL
);
292 log_error ("libksba did not return a proper S-Exp\n");
294 gcry_sexp_release (s_sig
);
295 return gpg_error (GPG_ERR_BUG
);
298 log_printhex ("public key: ", p
, n
);
300 rc
= gcry_sexp_sscan ( &s_pkey
, NULL
, p
, n
);
304 log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc
));
305 gcry_sexp_release (s_sig
);
310 rc
= do_encode_md (md
, algo
, pk_algo_from_sexp (s_pkey
),
311 gcry_pk_get_nbits (s_pkey
), &frame
);
314 gcry_sexp_release (s_sig
);
315 gcry_sexp_release (s_pkey
);
318 /* put hash into the S-Exp s_hash */
319 if ( gcry_sexp_build (&s_hash
, NULL
, "%m", frame
) )
321 gcry_mpi_release (frame
);
323 rc
= gcry_pk_verify (s_sig
, s_hash
, s_pkey
);
325 log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc
));
326 gcry_sexp_release (s_sig
);
327 gcry_sexp_release (s_hash
);
328 gcry_sexp_release (s_pkey
);
335 gpgsm_create_cms_signature (ctrl_t ctrl
, ksba_cert_t cert
,
336 gcry_md_hd_t md
, int mdalgo
, char **r_sigval
)
342 grip
= gpgsm_get_keygrip_hexstring (cert
);
344 return gpg_error (GPG_ERR_BAD_CERT
);
346 desc
= gpgsm_format_keydesc (cert
);
348 rc
= gpgsm_agent_pksign (ctrl
, grip
, desc
, gcry_md_read(md
, mdalgo
),
349 gcry_md_get_algo_dlen (mdalgo
), mdalgo
,