* certpath.c (check_cert_policy): New.

(gpgsm_validate_path): And call it from here.
* gpgsm.c (main): New options --policy-file,
--disable-policy-checks and --enable-policy-checks.
* gpgsm.h (opt): Added policy_file, no_policy_checks.
This commit is contained in:
Werner Koch 2002-02-19 17:39:05 +00:00
parent 2585114325
commit 488243f56e
6 changed files with 280 additions and 11 deletions

View File

@ -92,6 +92,8 @@ enum {
GNUPG_Card_Not_Present = 63,
GNUPG_No_PKCS15_App = 64,
GNUPG_Not_Confirmed = 65,
GNUPG_Configuration_Error = 66,
GNUPG_No_Policy_Match = 67,
};
/* Status codes - fixme: should go into another file */

View File

@ -1,3 +1,11 @@
2002-02-19 Werner Koch <wk@gnupg.org>
* certpath.c (check_cert_policy): New.
(gpgsm_validate_path): And call it from here.
* gpgsm.c (main): New options --policy-file,
--disable-policy-checks and --enable-policy-checks.
* gpgsm.h (opt): Added policy_file, no_policy_checks.
2002-02-18 Werner Koch <wk@gnupg.org>
* certpath.c (gpgsm_validate_path): Ask the agent to add the

View File

@ -84,6 +84,114 @@ allowed_ca (KsbaCert cert, int *pathlen)
return 0;
}
static int
check_cert_policy (KsbaCert cert)
{
KsbaError err;
char *policies;
FILE *fp;
int any_critical;
err = ksba_cert_get_cert_policies (cert, &policies);
if (err == KSBA_No_Data)
return 0; /* no policy given */
if (err)
return map_ksba_err (err);
/* STRING is a line delimited list of certifiate policies as stored
in the certificate. The line itself is colon delimted where the
first field is the OID of the policy and the second field either
N or C for normal or critical extension */
/* The check is very minimal but won't give false positives */
any_critical = !!strstr (policies, ":C");
if (!opt.policy_file)
{
xfree (policies);
if (any_critical)
{
log_error ("critical marked policy without configured policies\n");
return GNUPG_No_Policy_Match;
}
return 0;
}
fp = fopen (opt.policy_file, "r");
if (!fp)
{
log_error ("failed to open `%s': %s\n",
opt.policy_file, strerror (errno));
xfree (policies);
return GNUPG_Configuration_Error;
}
for (;;)
{
int c;
char *p, line[256];
char *haystack, *allowed;
/* read line */
do
{
if (!fgets (line, DIM(line)-1, fp) )
{
xfree (policies);
if (feof (fp))
{
fclose (fp);
log_error (_("certificate policy not allowed\n"));
/* with no critical policies this is only a warning */
return any_critical? GNUPG_No_Policy_Match : 0;
}
fclose (fp);
return GNUPG_Read_Error;
}
if (!*line || line[strlen(line)-1] != '\n')
{
/* eat until end of line */
while ( (c=getc (fp)) != EOF && c != '\n')
;
fclose (fp);
xfree (policies);
return *line? GNUPG_Line_Too_Long: GNUPG_Incomplete_Line;
}
/* Allow for empty lines and spaces */
for (p=line; spacep (p); p++)
;
}
while (!*p || *p == '\n' || *p == '#');
/* parse line */
for (allowed=line; spacep (allowed); allowed++)
;
p = strpbrk (allowed, " :\n");
if (!*p || p == allowed)
{
fclose (fp);
xfree (policies);
return GNUPG_Configuration_Error;
}
*p = 0; /* strip the rest of the line */
/* See whether we find ALLOWED (which is an OID) in POLICIES */
for (haystack=policies; (p=strstr (haystack, allowed)); haystack = p+1)
{
if ( !(p == policies || p[-1] == '\n') )
continue; /* does not match the begin of a line */
if (p[strlen (allowed)] != ':')
continue; /* the length does not match */
/* Yep - it does match so return okay */
fclose (fp);
xfree (policies);
return 0;
}
}
}
/* Return the next certificate up in the chain starting at START.
Returns -1 when there are no more certificates. */
int
@ -216,7 +324,14 @@ gpgsm_validate_path (KsbaCert cert)
rc = unknown_criticals (subject_cert);
if (rc)
goto leave;
if (!opt.no_policy_check)
{
rc = check_cert_policy (subject_cert);
if (rc)
goto leave;
}
if (!opt.no_crl_check)
{
rc = gpgsm_dirmngr_isvalid (subject_cert);
@ -360,9 +475,10 @@ gpgsm_validate_path (KsbaCert cert)
issuer_cert = NULL;
}
if (opt.no_policy_check)
log_info ("policies not checked due to --disable-policy-checks option\n");
if (opt.no_crl_check)
log_info ("CRL was not checked due to --no-crl-cechk option\n");
log_info ("CRLs not checked due to --disable-crl-checks option\n");
leave:
xfree (issuer);

View File

@ -84,6 +84,114 @@ allowed_ca (KsbaCert cert, int *pathlen)
return 0;
}
static int
check_cert_policy (KsbaCert cert)
{
KsbaError err;
char *policies;
FILE *fp;
int any_critical;
err = ksba_cert_get_cert_policies (cert, &policies);
if (err == KSBA_No_Data)
return 0; /* no policy given */
if (err)
return map_ksba_err (err);
/* STRING is a line delimited list of certifiate policies as stored
in the certificate. The line itself is colon delimted where the
first field is the OID of the policy and the second field either
N or C for normal or critical extension */
/* The check is very minimal but won't give false positives */
any_critical = !!strstr (policies, ":C");
if (!opt.policy_file)
{
xfree (policies);
if (any_critical)
{
log_error ("critical marked policy without configured policies\n");
return GNUPG_No_Policy_Match;
}
return 0;
}
fp = fopen (opt.policy_file, "r");
if (!fp)
{
log_error ("failed to open `%s': %s\n",
opt.policy_file, strerror (errno));
xfree (policies);
return GNUPG_Configuration_Error;
}
for (;;)
{
int c;
char *p, line[256];
char *haystack, *allowed;
/* read line */
do
{
if (!fgets (line, DIM(line)-1, fp) )
{
xfree (policies);
if (feof (fp))
{
fclose (fp);
log_error (_("certificate policy not allowed\n"));
/* with no critical policies this is only a warning */
return any_critical? GNUPG_No_Policy_Match : 0;
}
fclose (fp);
return GNUPG_Read_Error;
}
if (!*line || line[strlen(line)-1] != '\n')
{
/* eat until end of line */
while ( (c=getc (fp)) != EOF && c != '\n')
;
fclose (fp);
xfree (policies);
return *line? GNUPG_Line_Too_Long: GNUPG_Incomplete_Line;
}
/* Allow for empty lines and spaces */
for (p=line; spacep (p); p++)
;
}
while (!*p || *p == '\n' || *p == '#');
/* parse line */
for (allowed=line; spacep (allowed); allowed++)
;
p = strpbrk (allowed, " :\n");
if (!*p || p == allowed)
{
fclose (fp);
xfree (policies);
return GNUPG_Configuration_Error;
}
*p = 0; /* strip the rest of the line */
/* See whether we find ALLOWED (which is an OID) in POLICIES */
for (haystack=policies; (p=strstr (haystack, allowed)); haystack = p+1)
{
if ( !(p == policies || p[-1] == '\n') )
continue; /* does not match the begin of a line */
if (p[strlen (allowed)] != ':')
continue; /* the length does not match */
/* Yep - it does match so return okay */
fclose (fp);
xfree (policies);
return 0;
}
}
}
/* Return the next certificate up in the chain starting at START.
Returns -1 when there are no more certificates. */
int
@ -216,7 +324,14 @@ gpgsm_validate_path (KsbaCert cert)
rc = unknown_criticals (subject_cert);
if (rc)
goto leave;
if (!opt.no_policy_check)
{
rc = check_cert_policy (subject_cert);
if (rc)
goto leave;
}
if (!opt.no_crl_check)
{
rc = gpgsm_dirmngr_isvalid (subject_cert);
@ -360,9 +475,10 @@ gpgsm_validate_path (KsbaCert cert)
issuer_cert = NULL;
}
if (opt.no_policy_check)
log_info ("policies not checked due to --disable-policy-checks option\n");
if (opt.no_crl_check)
log_info ("CRL was not checked due to --no-crl-cechk option\n");
log_info ("CRLs not checked due to --disable-crl-checks option\n");
leave:
xfree (issuer);

View File

@ -100,10 +100,9 @@ enum cmd_and_opt_values {
oEnableCRLChecks,
oIncludeCerts,
oPolicyFile,
oDisablePolicyChecks,
oEnablePolicyChecks,
@ -242,6 +241,12 @@ static ARGPARSE_OPTS opts[] = {
{ oIncludeCerts, "include-certs", 1,
N_("|N|number of certificates to include") },
{ oPolicyFile, "policy-file", 2,
N_("|FILE|take policy information from FILE") },
{ oDisablePolicyChecks, "disable-policy-checks", 0,
N_("do not check certificate policies")},
{ oEnablePolicyChecks, "enable-policy-checks", 0, "@"},
#if 0
{ oDefRecipient, "default-recipient" ,2,
@ -654,6 +659,8 @@ main ( int argc, char **argv)
/* set the default option file */
if (default_config )
configname = make_filename (opt.homedir, "gpgsm.conf", NULL);
/* cet the default policy file */
opt.policy_file = make_filename (opt.homedir, "policies.txt", NULL);
argc = orig_argc;
argv = orig_argv;
@ -759,6 +766,22 @@ main ( int argc, char **argv)
case oIncludeCerts: ctrl.include_certs = pargs.r.ret_int; break;
case oPolicyFile:
xfree (opt.policy_file);
if (*pargs.r.ret_str)
opt.policy_file = xstrdup (pargs.r.ret_str);
else
opt.policy_file = NULL;
break;
case oDisablePolicyChecks:
opt.no_policy_check = 1;
break;
case oEnablePolicyChecks:
opt.no_policy_check = 0;
break;
case oOutput: opt.outfile = pargs.r.ret_str; break;

View File

@ -66,7 +66,10 @@ struct {
int ignore_time_conflict; /* Ignore certain time conflicts */
int no_crl_check; /* Don't do a CRL check */
int no_crl_check; /* Don't do a CRL check */
char *policy_file; /* full pathname of policy file */
int no_policy_check; /* ignore certificate policies */
} opt;
@ -208,6 +211,7 @@ int gpgsm_agent_pkdecrypt (const char *keygrip,
int gpgsm_agent_genkey (KsbaConstSexp keyparms, KsbaSexp *r_pubkey);
int gpgsm_agent_istrusted (KsbaCert cert);
int gpgsm_agent_havekey (const char *hexkeygrip);
int gpgsm_agent_marktrusted (KsbaCert cert);
/*-- call-dirmngr.c --*/
int gpgsm_dirmngr_isvalid (KsbaCert cert);