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_Card_Not_Present = 63,
|
||||||
GNUPG_No_PKCS15_App = 64,
|
GNUPG_No_PKCS15_App = 64,
|
||||||
GNUPG_Not_Confirmed = 65,
|
GNUPG_Not_Confirmed = 65,
|
||||||
|
GNUPG_Configuration_Error = 66,
|
||||||
|
GNUPG_No_Policy_Match = 67,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Status codes - fixme: should go into another file */
|
/* 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>
|
2002-02-18 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* certpath.c (gpgsm_validate_path): Ask the agent to add the
|
* certpath.c (gpgsm_validate_path): Ask the agent to add the
|
||||||
|
122
sm/certchain.c
122
sm/certchain.c
@ -84,6 +84,114 @@ allowed_ca (KsbaCert cert, int *pathlen)
|
|||||||
return 0;
|
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.
|
/* Return the next certificate up in the chain starting at START.
|
||||||
Returns -1 when there are no more certificates. */
|
Returns -1 when there are no more certificates. */
|
||||||
int
|
int
|
||||||
@ -216,7 +324,14 @@ gpgsm_validate_path (KsbaCert cert)
|
|||||||
rc = unknown_criticals (subject_cert);
|
rc = unknown_criticals (subject_cert);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
|
if (!opt.no_policy_check)
|
||||||
|
{
|
||||||
|
rc = check_cert_policy (subject_cert);
|
||||||
|
if (rc)
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
if (!opt.no_crl_check)
|
if (!opt.no_crl_check)
|
||||||
{
|
{
|
||||||
rc = gpgsm_dirmngr_isvalid (subject_cert);
|
rc = gpgsm_dirmngr_isvalid (subject_cert);
|
||||||
@ -360,9 +475,10 @@ gpgsm_validate_path (KsbaCert cert)
|
|||||||
issuer_cert = NULL;
|
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)
|
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:
|
leave:
|
||||||
xfree (issuer);
|
xfree (issuer);
|
||||||
|
122
sm/certpath.c
122
sm/certpath.c
@ -84,6 +84,114 @@ allowed_ca (KsbaCert cert, int *pathlen)
|
|||||||
return 0;
|
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.
|
/* Return the next certificate up in the chain starting at START.
|
||||||
Returns -1 when there are no more certificates. */
|
Returns -1 when there are no more certificates. */
|
||||||
int
|
int
|
||||||
@ -216,7 +324,14 @@ gpgsm_validate_path (KsbaCert cert)
|
|||||||
rc = unknown_criticals (subject_cert);
|
rc = unknown_criticals (subject_cert);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
|
if (!opt.no_policy_check)
|
||||||
|
{
|
||||||
|
rc = check_cert_policy (subject_cert);
|
||||||
|
if (rc)
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
if (!opt.no_crl_check)
|
if (!opt.no_crl_check)
|
||||||
{
|
{
|
||||||
rc = gpgsm_dirmngr_isvalid (subject_cert);
|
rc = gpgsm_dirmngr_isvalid (subject_cert);
|
||||||
@ -360,9 +475,10 @@ gpgsm_validate_path (KsbaCert cert)
|
|||||||
issuer_cert = NULL;
|
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)
|
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:
|
leave:
|
||||||
xfree (issuer);
|
xfree (issuer);
|
||||||
|
31
sm/gpgsm.c
31
sm/gpgsm.c
@ -100,10 +100,9 @@ enum cmd_and_opt_values {
|
|||||||
oEnableCRLChecks,
|
oEnableCRLChecks,
|
||||||
|
|
||||||
oIncludeCerts,
|
oIncludeCerts,
|
||||||
|
oPolicyFile,
|
||||||
|
oDisablePolicyChecks,
|
||||||
|
oEnablePolicyChecks,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -242,6 +241,12 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
{ oIncludeCerts, "include-certs", 1,
|
{ oIncludeCerts, "include-certs", 1,
|
||||||
N_("|N|number of certificates to include") },
|
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
|
#if 0
|
||||||
{ oDefRecipient, "default-recipient" ,2,
|
{ oDefRecipient, "default-recipient" ,2,
|
||||||
@ -654,6 +659,8 @@ main ( int argc, char **argv)
|
|||||||
/* set the default option file */
|
/* set the default option file */
|
||||||
if (default_config )
|
if (default_config )
|
||||||
configname = make_filename (opt.homedir, "gpgsm.conf", NULL);
|
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;
|
argc = orig_argc;
|
||||||
argv = orig_argv;
|
argv = orig_argv;
|
||||||
@ -759,6 +766,22 @@ main ( int argc, char **argv)
|
|||||||
|
|
||||||
case oIncludeCerts: ctrl.include_certs = pargs.r.ret_int; break;
|
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;
|
case oOutput: opt.outfile = pargs.r.ret_str; break;
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,7 +66,10 @@ struct {
|
|||||||
|
|
||||||
int ignore_time_conflict; /* Ignore certain time conflicts */
|
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;
|
} opt;
|
||||||
|
|
||||||
@ -208,6 +211,7 @@ int gpgsm_agent_pkdecrypt (const char *keygrip,
|
|||||||
int gpgsm_agent_genkey (KsbaConstSexp keyparms, KsbaSexp *r_pubkey);
|
int gpgsm_agent_genkey (KsbaConstSexp keyparms, KsbaSexp *r_pubkey);
|
||||||
int gpgsm_agent_istrusted (KsbaCert cert);
|
int gpgsm_agent_istrusted (KsbaCert cert);
|
||||||
int gpgsm_agent_havekey (const char *hexkeygrip);
|
int gpgsm_agent_havekey (const char *hexkeygrip);
|
||||||
|
int gpgsm_agent_marktrusted (KsbaCert cert);
|
||||||
|
|
||||||
/*-- call-dirmngr.c --*/
|
/*-- call-dirmngr.c --*/
|
||||||
int gpgsm_dirmngr_isvalid (KsbaCert cert);
|
int gpgsm_dirmngr_isvalid (KsbaCert cert);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user