signature clock skew code.

git-svn-id: file:///svn/unbound/trunk@1590 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2009-04-06 14:09:33 +00:00
parent 397985b2c8
commit 1e1ac9900a
13 changed files with 1300 additions and 1152 deletions

View file

@ -11,6 +11,7 @@
The example python scripts (pythonmod/examples and The example python scripts (pythonmod/examples and
libunbound/python/examples) are not installed. libunbound/python/examples) are not installed.
- python invalidate routine respects packed rrset ids and locks. - python invalidate routine respects packed rrset ids and locks.
- clock skew checks in unbound, config statements.
3 April 2009: Wouter 3 April 2009: Wouter
- Fixed a bug that caused messages to be stored in the cache too - Fixed a bug that caused messages to be stored in the cache too

View file

@ -319,6 +319,12 @@ server:
# some of the revalidation, until the time interval expires. in secs. # some of the revalidation, until the time interval expires. in secs.
# val-bogus-ttl: 60 # val-bogus-ttl: 60
# The signature inception and expiration dates are allowed to be off
# by 10% of the lifetime of the signature from our local clock.
# This leeway is capped with a minimum and a maximum. In seconds.
# val-sig-skew-min: 3600
# val-sig-skew-max: 86400
# Should additional section of secure message also be kept clean of # Should additional section of secure message also be kept clean of
# unsecure data. Useful to shield the users of this validator from # unsecure data. Useful to shield the users of this validator from
# potential bogus data in the additional section. All unsigned data # potential bogus data in the additional section. All unsigned data

View file

@ -528,6 +528,20 @@ giving a RRSIG style date, that date is used for verifying RRSIG inception
and expiration dates, instead of the current date. Do not set this unless and expiration dates, instead of the current date. Do not set this unless
you are debugging signature inception and expiration. you are debugging signature inception and expiration.
.TP .TP
.B val\-sig\-skew\-min: \fI<seconds>
Minimum number of seconds of clock skew to apply to validated signatures.
A value of 10% of the signature lifetime is used, capped by this setting.
Default is 3600 (1 hour) which allows for daylight savings differences.
Lower this value for more strict checking of short lived signatures.
.TP
.B val\-sig\-skew\-max: \fI<seconds>
Maximum number of seconds of clock skew to apply to validated signatures.
A value of 10% of the signature lifetime is used, capped by this setting.
Default is 86400 (24 hours) which allows for timezone setting problems in
stable domains. Setting both min and max very low disables the clock skew
allowances. Setting both min and max very high makes the validator check
the signature timestamps less strictly.
.TP
.B val\-bogus\-ttl: \fI<number> .B val\-bogus\-ttl: \fI<number>
The time to live for bogus data. This is data that has failed validation; The time to live for bogus data. This is data that has failed validation;
due to invalid signatures or other checks. The TTL from that data cannot be due to invalid signatures or other checks. The TTL from that data cannot be

View file

@ -148,6 +148,8 @@ config_create()
cfg->dlv_anchor_list = NULL; cfg->dlv_anchor_list = NULL;
cfg->domain_insecure = NULL; cfg->domain_insecure = NULL;
cfg->val_date_override = 0; cfg->val_date_override = 0;
cfg->val_sig_skew_min = 3600; /* at least daylight savings trouble */
cfg->val_sig_skew_max = 86400; /* at most timezone settings trouble */
cfg->val_clean_additional = 1; cfg->val_clean_additional = 1;
cfg->val_permissive_mode = 0; cfg->val_permissive_mode = 0;
cfg->key_cache_size = 4 * 1024 * 1024; cfg->key_cache_size = 4 * 1024 * 1024;

View file

@ -203,6 +203,10 @@ struct config_file {
int max_ttl; int max_ttl;
/** if not 0, this value is the validation date for RRSIGs */ /** if not 0, this value is the validation date for RRSIGs */
int32_t val_date_override; int32_t val_date_override;
/** the minimum for signature clock skew */
int32_t val_sig_skew_min;
/** the maximum for signature clock skew */
int32_t val_sig_skew_max;
/** this value sets the number of seconds before revalidating bogus */ /** this value sets the number of seconds before revalidating bogus */
int bogus_ttl; int bogus_ttl;
/** should validator clean additional section for secure msgs */ /** should validator clean additional section for secure msgs */

File diff suppressed because it is too large Load diff

View file

@ -190,6 +190,8 @@ trust-anchor-file{COLON} { YDVAR(1, VAR_TRUST_ANCHOR_FILE) }
trusted-keys-file{COLON} { YDVAR(1, VAR_TRUSTED_KEYS_FILE) } trusted-keys-file{COLON} { YDVAR(1, VAR_TRUSTED_KEYS_FILE) }
trust-anchor{COLON} { YDVAR(1, VAR_TRUST_ANCHOR) } trust-anchor{COLON} { YDVAR(1, VAR_TRUST_ANCHOR) }
val-override-date{COLON} { YDVAR(1, VAR_VAL_OVERRIDE_DATE) } val-override-date{COLON} { YDVAR(1, VAR_VAL_OVERRIDE_DATE) }
val-sig-skew-min{COLON} { YDVAR(1, VAR_VAL_SIG_SKEW_MIN) }
val-sig-skew-max{COLON} { YDVAR(1, VAR_VAL_SIG_SKEW_MAX) }
val-bogus-ttl{COLON} { YDVAR(1, VAR_BOGUS_TTL) } val-bogus-ttl{COLON} { YDVAR(1, VAR_BOGUS_TTL) }
val-clean-additional{COLON} { YDVAR(1, VAR_VAL_CLEAN_ADDITIONAL) } val-clean-additional{COLON} { YDVAR(1, VAR_VAL_CLEAN_ADDITIONAL) }
val-permissive-mode{COLON} { YDVAR(1, VAR_VAL_PERMISSIVE_MODE) } val-permissive-mode{COLON} { YDVAR(1, VAR_VAL_PERMISSIVE_MODE) }

File diff suppressed because it is too large Load diff

View file

@ -140,7 +140,9 @@
VAR_LOG_TIME_ASCII = 356, VAR_LOG_TIME_ASCII = 356,
VAR_DOMAIN_INSECURE = 357, VAR_DOMAIN_INSECURE = 357,
VAR_PYTHON = 358, VAR_PYTHON = 358,
VAR_PYTHON_SCRIPT = 359 VAR_PYTHON_SCRIPT = 359,
VAR_VAL_SIG_SKEW_MIN = 360,
VAR_VAL_SIG_SKEW_MAX = 361
}; };
#endif #endif
/* Tokens. */ /* Tokens. */
@ -246,6 +248,8 @@
#define VAR_DOMAIN_INSECURE 357 #define VAR_DOMAIN_INSECURE 357
#define VAR_PYTHON 358 #define VAR_PYTHON 358
#define VAR_PYTHON_SCRIPT 359 #define VAR_PYTHON_SCRIPT 359
#define VAR_VAL_SIG_SKEW_MIN 360
#define VAR_VAL_SIG_SKEW_MAX 361
@ -257,7 +261,7 @@ typedef union YYSTYPE
char* str; char* str;
} }
/* Line 1489 of yacc.c. */ /* Line 1489 of yacc.c. */
#line 261 "util/configparser.h" #line 265 "util/configparser.h"
YYSTYPE; YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_DECLARED 1

View file

@ -97,7 +97,8 @@ extern struct config_parser_state* cfg_parser;
%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE %token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
%token VAR_EXTENDED_STATISTICS VAR_LOCAL_DATA_PTR VAR_JOSTLE_TIMEOUT %token VAR_EXTENDED_STATISTICS VAR_LOCAL_DATA_PTR VAR_JOSTLE_TIMEOUT
%token VAR_STUB_PRIME VAR_UNWANTED_REPLY_THRESHOLD VAR_LOG_TIME_ASCII %token VAR_STUB_PRIME VAR_UNWANTED_REPLY_THRESHOLD VAR_LOG_TIME_ASCII
%token VAR_DOMAIN_INSECURE VAR_PYTHON VAR_PYTHON_SCRIPT %token VAR_DOMAIN_INSECURE VAR_PYTHON VAR_PYTHON_SCRIPT VAR_VAL_SIG_SKEW_MIN
%token VAR_VAL_SIG_SKEW_MAX
%% %%
toplevelvars: /* empty */ | toplevelvars toplevelvar ; toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -146,7 +147,8 @@ content_server: server_num_threads | server_verbosity | server_port |
server_private_domain | server_extended_statistics | server_private_domain | server_extended_statistics |
server_local_data_ptr | server_jostle_timeout | server_local_data_ptr | server_jostle_timeout |
server_unwanted_reply_threshold | server_log_time_ascii | server_unwanted_reply_threshold | server_log_time_ascii |
server_domain_insecure server_domain_insecure | server_val_sig_skew_min |
server_val_sig_skew_max
; ;
stubstart: VAR_STUB_ZONE stubstart: VAR_STUB_ZONE
{ {
@ -771,6 +773,32 @@ server_val_override_date: VAR_VAL_OVERRIDE_DATE STRING
free($2); free($2);
} }
; ;
server_val_sig_skew_min: VAR_VAL_SIG_SKEW_MIN STRING
{
OUTYY(("P(server_val_sig_skew_min:%s)\n", $2));
if(strlen($2) == 0 || strcmp($2, "0") == 0) {
cfg_parser->cfg->val_sig_skew_min = 0;
} else {
cfg_parser->cfg->val_sig_skew_min = atoi($2);
if(!cfg_parser->cfg->val_sig_skew_min)
yyerror("number expected");
}
free($2);
}
;
server_val_sig_skew_max: VAR_VAL_SIG_SKEW_MAX STRING
{
OUTYY(("P(server_val_sig_skew_max:%s)\n", $2));
if(strlen($2) == 0 || strcmp($2, "0") == 0) {
cfg_parser->cfg->val_sig_skew_max = 0;
} else {
cfg_parser->cfg->val_sig_skew_max = atoi($2);
if(!cfg_parser->cfg->val_sig_skew_max)
yyerror("number expected");
}
free($2);
}
;
server_cache_max_ttl: VAR_CACHE_MAX_TTL STRING server_cache_max_ttl: VAR_CACHE_MAX_TTL STRING
{ {
OUTYY(("P(server_cache_max_ttl:%s)\n", $2)); OUTYY(("P(server_cache_max_ttl:%s)\n", $2));

View file

@ -1073,13 +1073,29 @@ check_dates(struct val_env* ve, uint32_t unow,
return 0; return 0;
} }
if(incep - now > 0) { if(incep - now > 0) {
sigdate_error("verify: signature bad, current time is" /* within skew ? (calc here to avoid calculation normally) */
" before inception date", expi, incep, now); int32_t skew = (expi-incep)/10;
return 0; if(skew < ve->skew_min) skew = ve->skew_min;
if(skew > ve->skew_max) skew = ve->skew_max;
if(incep - now > skew) {
sigdate_error("verify: signature bad, current time is"
" before inception date", expi, incep, now);
return 0;
}
sigdate_error("verify warning suspicious signature inception "
" or bad local clock", expi, incep, now);
} }
if(now - expi > 0) { if(now - expi > 0) {
sigdate_error("verify: signature expired", expi, incep, now); int32_t skew = (expi-incep)/10;
return 0; if(skew < ve->skew_min) skew = ve->skew_min;
if(skew > ve->skew_max) skew = ve->skew_max;
if(now - expi > skew) {
sigdate_error("verify: signature expired", expi,
incep, now);
return 0;
}
sigdate_error("verify warning suspicious signature expiration "
" or bad local clock", expi, incep, now);
} }
return 1; return 1;

View file

@ -122,6 +122,8 @@ val_apply_cfg(struct module_env* env, struct val_env* val_env,
return 0; return 0;
} }
val_env->date_override = cfg->val_date_override; val_env->date_override = cfg->val_date_override;
val_env->skew_min = cfg->val_sig_skew_min;
val_env->skew_max = cfg->val_sig_skew_max;
c = cfg_count_numbers(cfg->val_nsec3_key_iterations); c = cfg_count_numbers(cfg->val_nsec3_key_iterations);
if(c < 1 || (c&1)) { if(c < 1 || (c&1)) {
log_err("validator: unparseable or odd nsec3 key " log_err("validator: unparseable or odd nsec3 key "

View file

@ -71,6 +71,12 @@ struct val_env {
* if 0, current time is used for rrsig validation */ * if 0, current time is used for rrsig validation */
int32_t date_override; int32_t date_override;
/** clock skew min for signatures */
int32_t skew_min;
/** clock skew max for signatures */
int32_t skew_max;
/** TTL for bogus data; used instead of untrusted TTL from data. /** TTL for bogus data; used instead of untrusted TTL from data.
* Bogus data will not be verified more often than this interval. * Bogus data will not be verified more often than this interval.
* seconds. */ * seconds. */