Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
IRMA
Github mirrors
irmago
Commits
1328a65d
Commit
1328a65d
authored
Apr 09, 2019
by
Sietse Ringers
Browse files
feat: support optional disjunctions by specifying an empty inner conjunction
parent
59166f5f
Changes
5
Hide whitespace changes
Inline
Side-by-side
internal/servercore/handle.go
View file @
1328a65d
...
...
@@ -95,16 +95,16 @@ func (session *session) handlePostCommitments(commitments *irma.IssueCommitmentM
session
.
markAlive
()
request
:=
session
.
request
.
(
*
irma
.
IssuanceRequest
)
discloseCount
:=
len
(
request
.
Disclose
)
if
len
(
commitments
.
Proofs
)
!=
len
(
request
.
Credentials
)
+
discloseCount
{
return
nil
,
session
.
fail
(
server
.
Error
AttributesMissing
,
"
"
)
discloseCount
:=
len
(
commitments
.
Proofs
)
-
len
(
request
.
Credentials
)
if
discloseCount
<
0
{
return
nil
,
session
.
fail
(
server
.
Error
MalformedInput
,
"Received insufficient proofs
"
)
}
// Compute list of public keys against which to verify the received proofs
disclosureproofs
:=
irma
.
ProofList
(
commitments
.
Proofs
[
:
discloseCount
])
pubkeys
,
err
:=
disclosureproofs
.
ExtractPublicKeys
(
session
.
conf
.
IrmaConfiguration
)
if
err
!=
nil
{
return
nil
,
session
.
fail
(
server
.
Error
InvalidProofs
,
err
.
Error
())
return
nil
,
session
.
fail
(
server
.
Error
MalformedInput
,
err
.
Error
())
}
for
_
,
cred
:=
range
request
.
Credentials
{
iss
:=
cred
.
CredentialTypeID
.
IssuerIdentifier
()
...
...
@@ -149,7 +149,10 @@ func (session *session) handlePostCommitments(commitments *irma.IssueCommitmentM
pk
,
_
:=
session
.
conf
.
IrmaConfiguration
.
PublicKey
(
id
,
cred
.
KeyCounter
)
sk
,
_
:=
session
.
conf
.
PrivateKey
(
id
)
issuer
:=
gabi
.
NewIssuer
(
sk
,
pk
,
one
)
proof
:=
commitments
.
Proofs
[
i
+
discloseCount
]
.
(
*
gabi
.
ProofU
)
proof
,
ok
:=
commitments
.
Proofs
[
i
+
discloseCount
]
.
(
*
gabi
.
ProofU
)
if
!
ok
{
return
nil
,
session
.
fail
(
server
.
ErrorMalformedInput
,
"Received invalid issuance commitment"
)
}
attributes
,
err
:=
cred
.
AttributeList
(
session
.
conf
.
IrmaConfiguration
,
0x03
)
if
err
!=
nil
{
return
nil
,
session
.
fail
(
server
.
ErrorIssuanceFailed
,
err
.
Error
())
...
...
internal/sessiontest/requestor_test.go
View file @
1328a65d
...
...
@@ -2,6 +2,7 @@ package sessiontest
import
(
"encoding/json"
"reflect"
"testing"
"github.com/privacybydesign/irmago"
...
...
@@ -163,3 +164,57 @@ func TestConDisCon(t *testing.T) {
requestorSessionHelper
(
t
,
dr
,
client
)
}
func
TestOptionalDisclosure
(
t
*
testing
.
T
)
{
client
:=
parseStorage
(
t
)
university
:=
irma
.
NewAttributeTypeIdentifier
(
"irma-demo.RU.studentCard.university"
)
studentid
:=
irma
.
NewAttributeTypeIdentifier
(
"irma-demo.RU.studentCard.studentID"
)
radboud
:=
"Radboud"
attrs1
:=
irma
.
AttributeConDisCon
{
irma
.
AttributeDisCon
{
// Including one non-optional disjunction is required in disclosure and signature sessions
irma
.
AttributeCon
{
irma
.
AttributeRequest
{
Type
:
university
}},
},
irma
.
AttributeDisCon
{
irma
.
AttributeCon
{},
irma
.
AttributeCon
{
irma
.
AttributeRequest
{
Type
:
studentid
}},
},
}
disclosed1
:=
[][]
*
irma
.
DisclosedAttribute
{
{
{
RawValue
:
&
radboud
,
Value
:
map
[
string
]
string
{
""
:
radboud
,
"en"
:
radboud
,
"nl"
:
radboud
},
Identifier
:
irma
.
NewAttributeTypeIdentifier
(
"irma-demo.RU.studentCard.university"
),
Status
:
irma
.
AttributeProofStatusPresent
,
},
},
{},
}
attrs2
:=
irma
.
AttributeConDisCon
{
// In issuance sessions, it is allowed that all disjunctions are optional
irma
.
AttributeDisCon
{
irma
.
AttributeCon
{},
irma
.
AttributeCon
{
irma
.
AttributeRequest
{
Type
:
studentid
}},
},
}
disclosed2
:=
[][]
*
irma
.
DisclosedAttribute
{{}}
tests
:=
[]
struct
{
request
irma
.
SessionRequest
attrs
irma
.
AttributeConDisCon
disclosed
[][]
*
irma
.
DisclosedAttribute
}{
{
irma
.
NewDisclosureRequest
(),
attrs1
,
disclosed1
},
{
irma
.
NewSignatureRequest
(
"message"
),
attrs1
,
disclosed1
},
{
getIssuanceRequest
(
true
),
attrs1
,
disclosed1
},
{
getIssuanceRequest
(
true
),
attrs2
,
disclosed2
},
}
for
_
,
args
:=
range
tests
{
args
.
request
.
Disclosure
()
.
Disclose
=
args
.
attrs
// TestHandler always prefers the first option when given any choice, so it will not disclose the optional attribute
result
:=
requestorSessionHelper
(
t
,
args
.
request
,
client
)
require
.
True
(
t
,
reflect
.
DeepEqual
(
args
.
disclosed
,
result
.
Disclosed
))
}
}
internal/sessiontest/server_test.go
View file @
1328a65d
...
...
@@ -12,6 +12,7 @@ import (
"github.com/privacybydesign/irmago/server/requestorserver"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
"github.com/x-cray/logrus-prefixed-formatter"
)
var
(
...
...
@@ -25,7 +26,7 @@ var (
func
init
()
{
logger
.
Level
=
logrus
.
ErrorLevel
logger
.
Formatter
=
&
logrus
.
TextFormatter
{}
logger
.
Formatter
=
&
prefixed
.
TextFormatter
{
ForceFormatting
:
true
,
ForceColors
:
true
}
}
func
StartRequestorServer
(
configuration
*
requestorserver
.
Configuration
)
{
...
...
irmaclient/client.go
View file @
1328a65d
...
...
@@ -515,6 +515,13 @@ func (client *Client) Candidates(discon irma.AttributeDisCon) (
candidates
=
[][]
*
irma
.
AttributeIdentifier
{}
for
_
,
con
:=
range
discon
{
if
len
(
con
)
==
0
{
// An empty conjunction means the containing disjunction is optional
// so it is satisfied by sending no attributes
candidates
=
append
(
candidates
,
[]
*
irma
.
AttributeIdentifier
{})
continue
}
// Build a list containing, for each attribute in this conjunction, a list of credential
// instances containing the attribute. Writing schematically a sample conjunction of three
// attribute types as [ a.a.a.a, a.a.a.b, a.a.b.x ], we map this to:
...
...
requests.go
View file @
1328a65d
...
...
@@ -206,7 +206,7 @@ func (c AttributeCon) CredentialTypes() []CredentialTypeIdentifier {
func
(
c
*
AttributeCon
)
MarshalJSON
()
([]
byte
,
error
)
{
var
vals
bool
m
:=
map
[
AttributeTypeIdentifier
]
*
string
{}
var
l
[]
AttributeTypeIdentifier
l
:=
make
(
[]
AttributeTypeIdentifier
,
0
,
len
(
*
c
))
for
_
,
attr
:=
range
*
c
{
m
[
attr
.
Type
]
=
attr
.
Value
...
...
@@ -256,34 +256,37 @@ func (ar *AttributeRequest) Satisfy(attr AttributeTypeIdentifier, val *string) b
return
ar
.
Type
==
attr
&&
(
ar
.
Value
==
nil
||
(
val
!=
nil
&&
*
ar
.
Value
==
*
val
))
}
func
(
c
AttributeCon
)
Satisfy
(
proofs
gabi
.
ProofList
,
indices
[]
*
DisclosedAttributeIndex
,
conf
*
Configuration
)
([]
*
DisclosedAttribute
,
error
)
{
func
(
c
AttributeCon
)
Satisfy
(
proofs
gabi
.
ProofList
,
indices
[]
*
DisclosedAttributeIndex
,
conf
*
Configuration
)
(
bool
,
[]
*
DisclosedAttribute
,
error
)
{
if
len
(
indices
)
<
len
(
c
)
{
return
nil
,
nil
return
false
,
nil
,
nil
}
attrs
:=
make
([]
*
DisclosedAttribute
,
0
,
len
(
c
))
if
len
(
c
)
==
0
{
return
true
,
attrs
,
nil
}
for
j
:=
range
c
{
index
:=
indices
[
j
]
attr
,
val
,
err
:=
extractAttribute
(
proofs
,
index
,
conf
)
if
err
!=
nil
{
return
nil
,
err
return
false
,
nil
,
err
}
if
!
c
[
j
]
.
Satisfy
(
attr
.
Identifier
,
val
)
{
return
nil
,
nil
return
false
,
nil
,
nil
}
attrs
=
append
(
attrs
,
attr
)
}
return
attrs
,
nil
return
true
,
attrs
,
nil
}
func
(
dc
AttributeDisCon
)
Satisfy
(
proofs
gabi
.
ProofList
,
indices
[]
*
DisclosedAttributeIndex
,
conf
*
Configuration
)
([]
*
DisclosedAttribute
,
error
)
{
func
(
dc
AttributeDisCon
)
Satisfy
(
proofs
gabi
.
ProofList
,
indices
[]
*
DisclosedAttributeIndex
,
conf
*
Configuration
)
(
bool
,
[]
*
DisclosedAttribute
,
error
)
{
for
_
,
con
:=
range
dc
{
attrs
,
err
:=
con
.
Satisfy
(
proofs
,
indices
,
conf
)
if
len
(
attrs
)
>
0
||
err
!=
nil
{
return
attrs
,
err
satisfied
,
attrs
,
err
:=
con
.
Satisfy
(
proofs
,
indices
,
conf
)
if
satisfied
||
err
!=
nil
{
return
true
,
attrs
,
err
}
}
return
nil
,
nil
return
false
,
nil
,
nil
}
func
(
cdc
AttributeConDisCon
)
Satisfy
(
disclosure
*
Disclosure
,
conf
*
Configuration
)
(
bool
,
[][]
*
DisclosedAttribute
,
error
)
{
...
...
@@ -294,11 +297,11 @@ func (cdc AttributeConDisCon) Satisfy(disclosure *Disclosure, conf *Configuratio
complete
:=
true
for
i
,
discon
:=
range
cdc
{
attrs
,
err
:=
discon
.
Satisfy
(
disclosure
.
Proofs
,
disclosure
.
Indices
[
i
],
conf
)
satisfied
,
attrs
,
err
:=
discon
.
Satisfy
(
disclosure
.
Proofs
,
disclosure
.
Indices
[
i
],
conf
)
if
err
!=
nil
{
return
false
,
nil
,
err
}
if
len
(
attrs
)
>
0
{
if
satisfied
{
list
[
i
]
=
attrs
}
else
{
complete
=
false
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment