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 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/>.
37 /* Return the number of bits of the Q parameter from the DSA key
40 get_dsa_qbits (gcry_sexp_t key
)
46 l1
= gcry_sexp_find_token (key
, "public-key", 0);
48 return 0; /* Does not contain a key object. */
49 l2
= gcry_sexp_cadr (l1
);
50 gcry_sexp_release (l1
);
51 l1
= gcry_sexp_find_token (l2
, "q", 1);
52 gcry_sexp_release (l2
);
54 return 0; /* Invalid object. */
55 q
= gcry_sexp_nth_mpi (l1
, 1, GCRYMPI_FMT_USG
);
56 gcry_sexp_release (l1
);
58 return 0; /* Missing value. */
59 nbits
= gcry_mpi_get_nbits (q
);
67 do_encode_md (gcry_md_hd_t md
, int algo
, int pkalgo
, unsigned int nbits
,
68 gcry_sexp_t pkey
, gcry_mpi_t
*r_val
)
74 if (pkalgo
== GCRY_PK_DSA
|| pkalgo
== GCRY_PK_ECDSA
)
78 if ( pkalgo
== GCRY_PK_ECDSA
)
79 qbits
= gcry_pk_get_nbits (pkey
);
81 qbits
= get_dsa_qbits (pkey
);
85 log_error(_("DSA requires the hash length to be a"
86 " multiple of 8 bits\n"));
87 return gpg_error (GPG_ERR_INTERNAL
);
90 /* Don't allow any Q smaller than 160 bits. We don't want
91 someone to issue signatures from a key with a 16-bit Q or
92 something like that, which would look correct but allow
93 trivial forgeries. Yes, I know this rules out using MD5 with
97 log_error (_("%s key uses an unsafe (%u bit) hash\n"),
98 gcry_pk_algo_name (pkalgo
), qbits
);
99 return gpg_error (GPG_ERR_INTERNAL
);
102 /* Check if we're too short. Too long is safe as we'll
103 automatically left-truncate. */
104 nframe
= gcry_md_get_algo_dlen (algo
);
105 if (nframe
< qbits
/8)
107 log_error (_("a %u bit hash is not valid for a %u bit %s key\n"),
108 (unsigned int)nframe
*8,
109 gcry_pk_get_nbits (pkey
),
110 gcry_pk_algo_name (pkalgo
));
111 /* FIXME: we need to check the requirements for ECDSA. */
112 if (nframe
< 20 || pkalgo
== GCRY_PK_DSA
)
113 return gpg_error (GPG_ERR_INTERNAL
);
116 frame
= xtrymalloc (nframe
);
118 return out_of_core ();
119 memcpy (frame
, gcry_md_read (md
, algo
), nframe
);
128 unsigned char asn
[100];
132 nframe
= (nbits
+7) / 8;
135 if (!algo
|| gcry_md_test_algo (algo
))
136 return gpg_error (GPG_ERR_DIGEST_ALGO
);
137 if (gcry_md_algo_info (algo
, GCRYCTL_GET_ASNOID
, asn
, &asnlen
))
139 log_error ("no object identifier for algo %d\n", algo
);
140 return gpg_error (GPG_ERR_INTERNAL
);
143 len
= gcry_md_get_algo_dlen (algo
);
145 if ( len
+ asnlen
+ 4 > nframe
)
147 log_error ("can't encode a %d bit MD into a %d bits frame\n",
148 (int)(len
*8), (int)nbits
);
149 return gpg_error (GPG_ERR_INTERNAL
);
152 /* We encode the MD in this way:
154 * 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
156 * PAD consists of FF bytes.
158 frame
= xtrymalloc (nframe
);
160 return out_of_core ();
163 frame
[n
++] = 1; /* block type */
164 i
= nframe
- len
- asnlen
-3 ;
166 memset ( frame
+n
, 0xff, i
); n
+= i
;
168 memcpy ( frame
+n
, asn
, asnlen
); n
+= asnlen
;
169 memcpy ( frame
+n
, gcry_md_read(md
, algo
), len
); n
+= len
;
170 assert ( n
== nframe
);
175 log_debug ("encoded hash:");
176 for (j
=0; j
< nframe
; j
++)
177 log_printf (" %02X", frame
[j
]);
181 gcry_mpi_scan (r_val
, GCRYMPI_FMT_USG
, frame
, n
, &nframe
);
186 /* Return the public key algorithm id from the S-expression PKEY.
187 FIXME: libgcrypt should provide such a function. Note that this
188 implementation uses the names as used by libksba. */
190 pk_algo_from_sexp (gcry_sexp_t pkey
)
197 l1
= gcry_sexp_find_token (pkey
, "public-key", 0);
199 return 0; /* Not found. */
200 l2
= gcry_sexp_cadr (l1
);
201 gcry_sexp_release (l1
);
203 name
= gcry_sexp_nth_data (l2
, 0, &n
);
205 algo
= 0; /* Not found. */
206 else if (n
==3 && !memcmp (name
, "rsa", 3))
208 else if (n
==3 && !memcmp (name
, "dsa", 3))
210 /* Because this function is called only for verification we can
211 assume that ECC actually means ECDSA. */
212 else if (n
==3 && !memcmp (name
, "ecc", 3))
213 algo
= GCRY_PK_ECDSA
;
214 else if (n
==13 && !memcmp (name
, "ambiguous-rsa", 13))
218 gcry_sexp_release (l2
);
223 /* Check the signature on CERT using the ISSUER-CERT. This function
224 does only test the cryptographic signature and nothing else. It is
225 assumed that the ISSUER_CERT is valid. */
227 gpgsm_check_cert_sig (ksba_cert_t issuer_cert
, ksba_cert_t cert
)
235 gcry_sexp_t s_sig
, s_hash
, s_pkey
;
237 algo
= gcry_md_map_name ( (algoid
=ksba_cert_get_digest_algo (cert
)));
240 log_error ("unknown hash algorithm `%s'\n", algoid
? algoid
:"?");
242 && ( !strcmp (algoid
, "1.2.840.113549.1.1.2")
243 ||!strcmp (algoid
, "1.2.840.113549.2.2")))
244 log_info (_("(this is the MD2 algorithm)\n"));
245 return gpg_error (GPG_ERR_GENERAL
);
247 rc
= gcry_md_open (&md
, algo
, 0);
250 log_error ("md_open failed: %s\n", gpg_strerror (rc
));
254 gcry_md_start_debug (md
, "hash.cert");
256 rc
= ksba_cert_hash (cert
, 1, HASH_FNC
, md
);
259 log_error ("ksba_cert_hash failed: %s\n", gpg_strerror (rc
));
265 p
= ksba_cert_get_sig_val (cert
);
266 n
= gcry_sexp_canon_len (p
, 0, NULL
, NULL
);
269 log_error ("libksba did not return a proper S-Exp\n");
272 return gpg_error (GPG_ERR_BUG
);
277 log_debug ("signature value:");
278 for (j
=0; j
< n
; j
++)
279 log_printf (" %02X", p
[j
]);
283 rc
= gcry_sexp_sscan ( &s_sig
, NULL
, (char*)p
, n
);
287 log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc
));
292 p
= ksba_cert_get_public_key (issuer_cert
);
293 n
= gcry_sexp_canon_len (p
, 0, NULL
, NULL
);
296 log_error ("libksba did not return a proper S-Exp\n");
299 gcry_sexp_release (s_sig
);
300 return gpg_error (GPG_ERR_BUG
);
302 rc
= gcry_sexp_sscan ( &s_pkey
, NULL
, (char*)p
, n
);
306 log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc
));
308 gcry_sexp_release (s_sig
);
312 rc
= do_encode_md (md
, algo
, pk_algo_from_sexp (s_pkey
),
313 gcry_pk_get_nbits (s_pkey
), s_pkey
, &frame
);
317 gcry_sexp_release (s_sig
);
318 gcry_sexp_release (s_pkey
);
322 /* put hash into the S-Exp s_hash */
323 if ( gcry_sexp_build (&s_hash
, NULL
, "%m", frame
) )
325 gcry_mpi_release (frame
);
328 rc
= gcry_pk_verify (s_sig
, s_hash
, s_pkey
);
330 log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc
));
332 gcry_sexp_release (s_sig
);
333 gcry_sexp_release (s_hash
);
334 gcry_sexp_release (s_pkey
);
341 gpgsm_check_cms_signature (ksba_cert_t cert
, ksba_const_sexp_t sigval
,
342 gcry_md_hd_t md
, int mdalgo
, int *r_pkalgo
)
347 gcry_sexp_t s_sig
, s_hash
, s_pkey
;
354 n
= gcry_sexp_canon_len (sigval
, 0, NULL
, NULL
);
357 log_error ("libksba did not return a proper S-Exp\n");
358 return gpg_error (GPG_ERR_BUG
);
360 rc
= gcry_sexp_sscan (&s_sig
, NULL
, (char*)sigval
, n
);
363 log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc
));
367 p
= ksba_cert_get_public_key (cert
);
368 n
= gcry_sexp_canon_len (p
, 0, NULL
, NULL
);
371 log_error ("libksba did not return a proper S-Exp\n");
373 gcry_sexp_release (s_sig
);
374 return gpg_error (GPG_ERR_BUG
);
377 log_printhex ("public key: ", p
, n
);
379 rc
= gcry_sexp_sscan ( &s_pkey
, NULL
, (char*)p
, n
);
383 log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc
));
384 gcry_sexp_release (s_sig
);
388 pkalgo
= pk_algo_from_sexp (s_pkey
);
391 rc
= do_encode_md (md
, mdalgo
, pkalgo
,
392 gcry_pk_get_nbits (s_pkey
), s_pkey
, &frame
);
395 gcry_sexp_release (s_sig
);
396 gcry_sexp_release (s_pkey
);
399 /* put hash into the S-Exp s_hash */
400 if ( gcry_sexp_build (&s_hash
, NULL
, "%m", frame
) )
402 gcry_mpi_release (frame
);
404 rc
= gcry_pk_verify (s_sig
, s_hash
, s_pkey
);
406 log_debug ("gcry_pk_verify: %s\n", gpg_strerror (rc
));
407 gcry_sexp_release (s_sig
);
408 gcry_sexp_release (s_hash
);
409 gcry_sexp_release (s_pkey
);
416 gpgsm_create_cms_signature (ctrl_t ctrl
, ksba_cert_t cert
,
417 gcry_md_hd_t md
, int mdalgo
,
418 unsigned char **r_sigval
)
424 grip
= gpgsm_get_keygrip_hexstring (cert
);
426 return gpg_error (GPG_ERR_BAD_CERT
);
428 desc
= gpgsm_format_keydesc (cert
);
430 rc
= gpgsm_agent_pksign (ctrl
, grip
, desc
, gcry_md_read(md
, mdalgo
),
431 gcry_md_get_algo_dlen (mdalgo
), mdalgo
,