Commit 79a16c29 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

feat: allow at most one non-singleton credential within an inner conjunction

parent 68d589ba
......@@ -168,8 +168,10 @@ func (s *Server) verifyConfiguration(configuration *server.Configuration) error
}
func (s *Server) validateRequest(request irma.SessionRequest) error {
_, err := s.conf.IrmaConfiguration.Download(request)
return err
if _, err := s.conf.IrmaConfiguration.Download(request); err != nil {
return err
}
return request.Disclosure().Disclose.Validate(s.conf.IrmaConfiguration)
}
func (s *Server) StartSession(req interface{}) (*irma.Qr, string, error) {
......
......@@ -230,7 +230,8 @@ func serverName(hostname string, request irma.SessionRequest, conf *irma.Configu
func (session *session) processSessionInfo() {
defer session.recoverFromPanic()
if !session.checkAndUpateConfiguration() {
if err := session.checkAndUpateConfiguration(); err != nil {
session.fail(err.(*irma.SessionError))
return
}
......@@ -490,15 +491,13 @@ func (session *session) checkKeyshareEnrollment() bool {
return true
}
func (session *session) checkAndUpateConfiguration() bool {
func (session *session) checkAndUpateConfiguration() error {
// Download missing credential types/issuers/public keys from the scheme manager
downloaded, err := session.client.Configuration.Download(session.request)
if uerr, ok := err.(*irma.UnknownIdentifierError); ok {
session.fail(&irma.SessionError{ErrorType: uerr.ErrorType, Err: uerr})
return false
return &irma.SessionError{ErrorType: uerr.ErrorType, Err: uerr}
} else if err != nil {
session.fail(&irma.SessionError{ErrorType: irma.ErrorConfigurationDownload, Err: err})
return false
return &irma.SessionError{ErrorType: irma.ErrorConfigurationDownload, Err: err}
}
if downloaded != nil && !downloaded.Empty() {
session.client.handler.UpdateConfiguration(downloaded)
......@@ -506,10 +505,14 @@ func (session *session) checkAndUpateConfiguration() bool {
// Check if we are enrolled into all involved keyshare servers
if !session.checkKeyshareEnrollment() {
return false
return &irma.SessionError{ErrorType: irma.ErrorKeyshare}
}
return true
if err = session.request.Disclosure().Disclose.Validate(session.client.Configuration); err != nil {
return &irma.SessionError{ErrorType: irma.ErrorInvalidRequest}
}
return nil
}
// IsInteractive returns whether this session uses an API server or not.
......
......@@ -468,3 +468,53 @@ func TestSessionRequests(t *testing.T) {
func trivialTranslation(str string) TranslatedString {
return TranslatedString{"en": str, "nl": str}
}
func TestConDisconSingletons(t *testing.T) {
tests := []struct {
attrs AttributeConDisCon
allowed bool
}{
{
AttributeConDisCon{
AttributeDisCon{
AttributeCon{
NewAttributeRequest("irma-demo.RU.studentCard.studentID"), // singleton
NewAttributeRequest("test.test.email.email"), // singleton
},
},
},
false, // multiple singletons in one inner conjunction is not allowed
},
{
AttributeConDisCon{
AttributeDisCon{
AttributeCon{
NewAttributeRequest("irma-demo.RU.studentCard.studentID"), // non singleton
NewAttributeRequest("test.test.mijnirma.email"), // non singleton
},
},
},
true,
},
{
AttributeConDisCon{
AttributeDisCon{
AttributeCon{
NewAttributeRequest("irma-demo.MijnOverheid.root.BSN"), // singleton
NewAttributeRequest("test.test.mijnirma.email"), // non singleton
},
},
},
true,
},
}
conf := parseConfiguration(t)
for _, args := range tests {
if args.allowed {
require.NoError(t, args.attrs.Validate(conf))
} else {
require.Error(t, args.attrs.Validate(conf))
}
}
}
......@@ -196,6 +196,8 @@ const (
ErrorUnknownSchemeManager = ErrorType("unknownSchemeManager")
// A session is requested involving a scheme manager that has some problem
ErrorInvalidSchemeManager = ErrorType("invalidSchemeManager")
// Invalid session request
ErrorInvalidRequest = ErrorType("invalidRequest")
// Recovered panic
ErrorPanic = ErrorType("panic")
)
......
......@@ -289,6 +289,25 @@ func (dc AttributeDisCon) Satisfy(proofs gabi.ProofList, indices []*DisclosedAtt
return false, nil, nil
}
func (cdc AttributeConDisCon) Validate(conf *Configuration) error {
for _, discon := range cdc {
for _, con := range discon {
var nonsingleton *CredentialTypeIdentifier
for _, attr := range con {
typ := attr.Type.CredentialTypeIdentifier()
if !conf.CredentialTypes[typ].IsSingleton {
if nonsingleton != nil && *nonsingleton != typ {
return errors.New("Multiple non-singletons within one inner conjunction are not allowed")
} else {
nonsingleton = &typ
}
}
}
}
}
return nil
}
func (cdc AttributeConDisCon) Satisfy(disclosure *Disclosure, conf *Configuration) (bool, [][]*DisclosedAttribute, error) {
if len(disclosure.Indices) < len(cdc) {
return false, nil, nil
......
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