Commit 113979e7 authored by Sietse Ringers's avatar Sietse Ringers

feat: make maximum nonrevocation duration configurable per credential type

parent e19d7a94
......@@ -87,7 +87,7 @@ func (entry *LogEntry) GetDisclosedCredentials(conf *irma.Configuration) ([][]*i
} else {
disclosure = entry.Disclosure
}
_, attrs, err := disclosure.DisclosedAttributes(conf, disjunctions.Disclose)
_, attrs, err := disclosure.DisclosedAttributes(conf, disjunctions.Disclose, nil)
return attrs, err
}
......
......@@ -40,8 +40,9 @@ type (
// RevocationSetting contains revocation settings for a given credential type.
RevocationSetting struct {
Mode RevocationMode `json:"mode"`
PostURLs []string `json:"post_urls" mapstructure:"post_urls"`
Mode RevocationMode `json:"mode"`
PostURLs []string `json:"post_urls" mapstructure:"post_urls"`
MaxNonrevocationDuration uint `json:"max_nonrev_duration" mapstructure:"max_nonrev_duration"` // in seconds, min 30
// set to now whenever a new revocation record is received, or when the RA indicates
// there are no new records. Thus it specifies up to what time our nonrevocation
......@@ -102,11 +103,11 @@ const (
// for the client to update its revocation state.
revocationUpdateCount = 5
// revocationMaxAccumulatorAge is the default maximum for the 'accumulator age', which we
// define to be the amount of time since the last confirmation from the RA that the latest
// accumulator that we know is still the latest one: clients should prove nonrevocation
// revocationMaxAccumulatorAge is the default maximum in seconds for the 'accumulator age',
// which we define to be the amount of time since the last confirmation from the RA that the
// latest accumulator that we know is still the latest one: clients should prove nonrevocation
// against a 'younger' accumulator.
revocationMaxAccumulatorAge = 5 * time.Minute
revocationMaxAccumulatorAge uint = 5 * 60
)
// Revocation record methods
......@@ -361,8 +362,9 @@ func (rs *RevocationStorage) UpdateDB(typ CredentialTypeIdentifier) error {
}
func (rs *RevocationStorage) UpdateIfOld(typ CredentialTypeIdentifier) error {
settings := rs.getSettings(typ)
// update 10 seconds before the maximum, to stay below it
if rs.getSettings(typ).updated.Before(time.Now().Add(-revocationMaxAccumulatorAge + 10*time.Second)) {
if settings.updated.Before(time.Now().Add(time.Duration(-settings.MaxNonrevocationDuration+10) * time.Second)) {
if err := rs.UpdateDB(typ); err != nil {
return err
}
......@@ -435,6 +437,12 @@ func (rs *RevocationStorage) Load(debug bool, connstr string, settings map[Crede
} else {
rs.settings = map[CredentialTypeIdentifier]*RevocationSetting{}
}
for id, settings := range rs.settings {
if settings.MaxNonrevocationDuration != 0 && settings.MaxNonrevocationDuration < 30 {
return errors.Errorf("max_nonrev_duration setting for %s must be at least 30 seconds, was %d",
id, settings.MaxNonrevocationDuration)
}
}
rs.client = RevocationClient{Conf: rs.conf}
rs.Keys = RevocationKeys{Conf: rs.conf}
return nil
......@@ -483,7 +491,11 @@ func (rs *RevocationStorage) getSettings(typ CredentialTypeIdentifier) *Revocati
if rs.settings[typ] == nil {
rs.settings[typ] = &RevocationSetting{}
}
return rs.settings[typ]
s := rs.settings[typ]
if s.MaxNonrevocationDuration == 0 {
s.MaxNonrevocationDuration = revocationMaxAccumulatorAge
}
return s
}
func (RevocationClient) PostRevocationRecords(urls []string, records []*RevocationRecord) {
......
......@@ -185,9 +185,9 @@ func (pl ProofList) VerifyProofs(
return false, nil, errors.New("nonrevocation proof used wrong accumulator")
}
if ours == theirs {
accAge := configuration.RevocationStorage.getSettings(id).updated
if time.Now().Sub(accAge) > revocationMaxAccumulatorAge {
revocation[i] = &accAge
settings := configuration.RevocationStorage.getSettings(id)
if uint(time.Now().Sub(settings.updated).Seconds()) > settings.MaxNonrevocationDuration {
revocation[i] = &settings.updated
}
}
}
......@@ -236,6 +236,9 @@ func (d *Disclosure) extraIndices(condiscon AttributeConDisCon) []*DisclosedAttr
// the disjunction list. The first return parameter of this function indicates whether or not all
// disjunctions (if present) are satisfied.
func (d *Disclosure) DisclosedAttributes(configuration *Configuration, condiscon AttributeConDisCon, revocation map[int]*time.Time) (bool, [][]*DisclosedAttribute, error) {
if revocation == nil {
revocation = map[int]*time.Time{}
}
complete, list, err := condiscon.Satisfy(d, revocation, configuration)
if err != nil {
return false, nil, err
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment