mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
* 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:
parent
2585114325
commit
488243f56e
@ -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 */
|
||||
|
@ -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
|
||||
|
120
sm/certchain.c
120
sm/certchain.c
@ -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
|
||||
@ -217,6 +325,13 @@ gpgsm_validate_path (KsbaCert 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);
|
||||
|
120
sm/certpath.c
120
sm/certpath.c
@ -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
|
||||
@ -217,6 +325,13 @@ gpgsm_validate_path (KsbaCert 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);
|
||||
|
31
sm/gpgsm.c
31
sm/gpgsm.c
@ -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;
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user