1
1
/* certchain.c - certificate chain validation
2
* Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
2
* Copyright (C) 2001, 2002, 2003, 2004, 2005,
3
* 2006 Free Software Foundation, Inc.
4
5
* This file is part of GnuPG.
16
17
* You should have received a copy of the GNU General Public License
17
18
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21
23
#include <config.h>
1197
/* Check whether the certificate CERT has been issued by the German
1198
authority for qualified signature. They do not set the
1199
basicConstraints and thus we need this workaround. It works by
1200
looking up the root certificate and checking whether that one is
1201
listed as a qualified certificate for Germany.
1203
We also try to cache this data but as long as don't keep a
1204
reference to the certificate this won't be used.
1206
Returns: True if CERT is a RegTP issued CA cert (i.e. the root
1207
certificate itself or one of the CAs). In that case CHAINLEN will
1208
receive the length of the chain which is either 0 or 1.
1211
get_regtp_ca_info (ksba_cert_t cert, int *chainlen)
1218
ksba_cert_t array[4];
1224
chainlen = &dummy_chainlen;
1227
err = ksba_cert_get_user_data (cert, "regtp_ca_chainlen",
1228
&buf, sizeof (buf), &buflen);
1232
if (buflen < 2 || !*buf)
1233
return 0; /* Nothing found. */
1235
return 1; /* This is a regtp CA. */
1237
else if (gpg_err_code (err) != GPG_ERR_NOT_FOUND)
1239
log_error ("ksba_cert_get_user_data(%s) failed: %s\n",
1240
"regtp_ca_chainlen", gpg_strerror (err));
1241
return 0; /* Nothing found. */
1244
/* Need to gather the info. This requires to walk up the chain
1245
until we have found the root. Because we are only interested in
1246
German Bundesnetzagentur (former RegTP) derived certificates 3
1247
levels are enough. (The German signature law demands a 3 tier
1248
hierachy; thus there is only one CA between the EE and the Root
1250
memset (&array, 0, sizeof array);
1253
ksba_cert_ref (cert);
1254
array[depth++] = cert;
1255
ksba_cert_ref (cert);
1256
while (depth < DIM(array) && !(rc=gpgsm_walk_cert_chain (cert, &next)))
1258
ksba_cert_release (cert);
1259
ksba_cert_ref (next);
1260
array[depth++] = next;
1263
ksba_cert_release (cert);
1264
if (rc != -1 || !depth || depth == DIM(array) )
1266
/* We did not reached the root. */
1270
/* If this is a German signature law issued certificate, we store
1271
additional additional information. */
1272
if (!gpgsm_is_in_qualified_list (NULL, array[depth-1], country)
1273
&& !strcmp (country, "de"))
1275
/* Setting the pathlen for the root CA and the CA flag for the
1276
next one is all what we need to do. */
1277
err = ksba_cert_set_user_data (array[depth-1], "regtp_ca_chainlen",
1279
if (!err && depth > 1)
1280
err = ksba_cert_set_user_data (array[depth-2], "regtp_ca_chainlen",
1283
log_error ("ksba_set_user_data(%s) failed: %s\n",
1284
"regtp_ca_chainlen", gpg_strerror (err));
1285
for (i=0; i < depth; i++)
1286
ksba_cert_release (array[i]);
1287
*chainlen = (depth>1? 0:1);
1292
/* Nothing special with this certificate. Mark the target
1293
certificate anyway to avoid duplicate lookups. */
1294
err = ksba_cert_set_user_data (cert, "regtp_ca_chainlen", "", 1);
1296
log_error ("ksba_set_user_data(%s) failed: %s\n",
1297
"regtp_ca_chainlen", gpg_strerror (err));
1298
for (i=0; i < depth; i++)
1299
ksba_cert_release (array[i]);