Commit dfc27bea authored by Koen van Ingen's avatar Koen van Ingen
Browse files

Refactor and use different types for proof results

parent 1ac28e84
...@@ -22,18 +22,18 @@ const ( ...@@ -22,18 +22,18 @@ const (
type AttributeResultList struct { type AttributeResultList struct {
AttributeResults []*AttributeResult AttributeResults []*AttributeResult
} }
type AttributeResult struct { type AttributeResult struct {
AttributeValue TranslatedString // Value of the disclosed attribute AttributeValue string `json:"value"` // Value of the disclosed attribute
AttributeId AttributeTypeIdentifier AttributeId AttributeTypeIdentifier `json:"id"`
AttributeProofStatus AttributeProofStatus AttributeProofStatus AttributeProofStatus `json:"status"`
} }
// AttributeProofStatus is the proof status of a single attribute
type AttributeProofStatus string type AttributeProofStatus string
const ( const (
PRESENT = AttributeProofStatus("PRESENT") // Attribute is disclosed and matches the value PRESENT = AttributeProofStatus("PRESENT") // Attribute is disclosed and matches the value
UNKNOWN = AttributeProofStatus("UNKNOWN") // Attribute is disclosed, but status is yet unknown EXTRA = AttributeProofStatus("EXTRA")
MISSING = AttributeProofStatus("MISSING") // Attribute is NOT disclosed, but should be according to request MISSING = AttributeProofStatus("MISSING") // Attribute is NOT disclosed, but should be according to request
INVALID_VALUE = AttributeProofStatus("INVALID_VALUE") // Attribute is disclosed, but has invalid value according to request INVALID_VALUE = AttributeProofStatus("INVALID_VALUE") // Attribute is disclosed, but has invalid value according to request
) )
...@@ -54,7 +54,7 @@ type metadataField struct { ...@@ -54,7 +54,7 @@ type metadataField struct {
offset int offset int
} }
// MetadataAttribute represent a metadata attribute. Contains the credential type, signing date, validity, and the public key counter. // metadataAttribute represents a metadata attribute. Contains the credential type, signing date, validity, and the public key counter.
type MetadataAttribute struct { type MetadataAttribute struct {
Int *big.Int Int *big.Int
pk *gabi.PublicKey pk *gabi.PublicKey
...@@ -79,16 +79,6 @@ func NewAttributeListFromInts(ints []*big.Int, conf *Configuration) *AttributeLi ...@@ -79,16 +79,6 @@ func NewAttributeListFromInts(ints []*big.Int, conf *Configuration) *AttributeLi
} }
} }
// NewAttributeListFromInts initializes a new AttributeList from disclosed attributes of a prooflist
func NewAttributeListFromADisclosed(aResponses map[int]*big.Int, aDisclosed map[int]*big.Int, conf *Configuration) (*AttributeList, error) {
ints, err := convertProofResponsesToInts(aResponses, aDisclosed)
if err != nil {
return nil, err
}
return NewAttributeListFromInts(ints, conf), nil
}
func (al *AttributeList) Info() *CredentialInfo { func (al *AttributeList) Info() *CredentialInfo {
if al.info == nil { if al.info == nil {
al.info = NewCredentialInfo(al.Ints, al.Conf) al.info = NewCredentialInfo(al.Ints, al.Conf)
...@@ -323,9 +313,27 @@ type AttributeDisjunction struct { ...@@ -323,9 +313,27 @@ type AttributeDisjunction struct {
selected *AttributeTypeIdentifier selected *AttributeTypeIdentifier
} }
// AttributeDisjunction with the disclosed value. Label, Attributes,Valued can be nil if there is no matching disjunction
type DisclosedAttributeDisjunction struct {
AttributeDisjunction
DisclosedValue string
DisclosedId AttributeTypeIdentifier
ProofStatus AttributeProofStatus
}
// An AttributeDisjunctionList is a list of AttributeDisjunctions. // An AttributeDisjunctionList is a list of AttributeDisjunctions.
type AttributeDisjunctionList []*AttributeDisjunction type AttributeDisjunctionList []*AttributeDisjunction
func NewDisclosedDisjunctionFromList(ad *AttributeDisjunction, ar *AttributeResult) *DisclosedAttributeDisjunction {
return &DisclosedAttributeDisjunction{
AttributeDisjunction: *ad,
DisclosedValue: ar.AttributeValue,
DisclosedId: ar.AttributeId,
ProofStatus: ar.AttributeProofStatus,
}
}
// HasValues indicates if the attributes of this disjunction have values // HasValues indicates if the attributes of this disjunction have values
// that should be satisfied. // that should be satisfied.
func (disjunction *AttributeDisjunction) HasValues() bool { func (disjunction *AttributeDisjunction) HasValues() bool {
...@@ -350,58 +358,60 @@ func (disjunction *AttributeDisjunction) Satisfied() bool { ...@@ -350,58 +358,60 @@ func (disjunction *AttributeDisjunction) Satisfied() bool {
// This is the case if: // This is the case if:
// attribute is contained in disclosed AND if a value is present: equal to that value // attribute is contained in disclosed AND if a value is present: equal to that value
// al can be nil if you don't want to include attribute status for proof // al can be nil if you don't want to include attribute status for proof
func isAttributeSatisfied(attribute AttributeTypeIdentifier, value string, disclosed []*CredentialInfo, conf *Configuration, al *AttributeResultList) bool { func isAttributeSatisfied(attributeId AttributeTypeIdentifier, requestedValue string, disclosed []*DisclosedCredential) (bool, *AttributeResult) {
ar := AttributeResult{
AttributeId: attributeId,
}
for _, cred := range disclosed { for _, cred := range disclosed {
credentialType := cred.GetCredentialType(conf) disclosedAttributeValue := cred.GetAttributeValue(attributeId)
index, err := credentialType.IndexOf(attribute)
if err != nil { // Continue to next credential if requested attribute isn't disclosed in this credential
// Specified credential does not contain this attribute, move to next cred in list of disclosed credentials if disclosedAttributeValue == "" {
continue continue
} }
disclosedAttributeValue := cred.Attributes[index] // If this is the disclosed attribute, check if value matches
// If it contains this attribute, check if value matches (it must be disclosed (i.e. not nil) and match the value)
// Attribute is satisfied if: // Attribute is satisfied if:
// - Attribute is disclosed (i.e. not nil) // - Attribute is disclosed (i.e. not nil)
// - Value is empty OR value equal to disclosedValue // - Value is empty OR value equal to disclosedValue
if disclosedAttributeValue != nil { ar.AttributeValue = disclosedAttributeValue
if value == "" || disclosedAttributeValue["en"] == value { // TODO: fix translation/attr typing
al.SetProofStatus(attribute, disclosedAttributeValue, PRESENT) if requestedValue == "" || disclosedAttributeValue == requestedValue {
return true ar.AttributeProofStatus = PRESENT
return true, &ar
} else { } else {
// If attribute is disclosed and present, but not equal to required value, mark it as invalid_value // If attribute is disclosed and present, but not equal to required value, mark it as invalid_value
// We won't return true and continue searching in other disclosed attributes // We won't return true and continue searching in other disclosed attributes
al.SetProofStatus(attribute, disclosedAttributeValue, INVALID_VALUE) ar.AttributeProofStatus = INVALID_VALUE
} }
} }
// If there is never a value assigned, then this attribute isn't disclosed, and thus missing
if ar.AttributeValue == "" {
ar.AttributeProofStatus = MISSING
} }
return false return false, &ar
} }
// Check whether specified attributedisjunction satisfy a list of disclosed attributes // Check whether specified attributedisjunction satisfy a list of disclosed attributes
// We return true if one of the attributes in the disjunction is satisfied // We return true if one of the attributes in the disjunction is satisfied
func (disjunction *AttributeDisjunction) SatisfyDisclosed(disclosed []*CredentialInfo, conf *Configuration, al *AttributeResultList) bool { func (disjunction *AttributeDisjunction) SatisfyDisclosed(disclosed []*DisclosedCredential, conf *Configuration) (bool, *DisclosedAttributeDisjunction) {
var attributeResult *AttributeResult
for _, attr := range disjunction.Attributes { for _, attr := range disjunction.Attributes {
value := disjunction.Values[attr] requestedValue := disjunction.Values[attr]
if isAttributeSatisfied(attr, value, disclosed, conf, al) { var isSatisfied bool
return true isSatisfied, attributeResult = isAttributeSatisfied(attr, requestedValue, disclosed)
}
}
// Add all missing attributes if isSatisfied {
for _, attr := range disjunction.Attributes { return true, NewDisclosedDisjunctionFromList(disjunction, attributeResult)
ar := AttributeResult{
AttributeId: attr,
AttributeProofStatus: MISSING,
}
if !al.ContainsAttributeId(ar.AttributeId) {
al.Append(ar)
} }
} }
return false // Nothing satisfied, attributeResult will contain the last attribute of the original request
// TODO: do we want this?
return false, NewDisclosedDisjunctionFromList(disjunction, attributeResult)
} }
// MatchesConfig returns true if all attributes contained in the disjunction are // MatchesConfig returns true if all attributes contained in the disjunction are
...@@ -517,19 +527,8 @@ func (disjunction *AttributeDisjunction) UnmarshalJSON(bytes []byte) error { ...@@ -517,19 +527,8 @@ func (disjunction *AttributeDisjunction) UnmarshalJSON(bytes []byte) error {
return nil return nil
} }
// From here attributeResult related functions. TODO: move to separate file? func (al *AttributeResultList) Append(result *AttributeResult) {
al.AttributeResults = append(al.AttributeResults, result)
func (al *AttributeResultList) Append(result AttributeResult) {
al.AttributeResults = append(al.AttributeResults, &result)
}
func (al *AttributeResultList) ContainsAttributeId(attrId AttributeTypeIdentifier) bool {
for _, ar := range al.AttributeResults {
if ar.AttributeId == attrId {
return true
}
}
return false
} }
func (al *AttributeResultList) String() string { func (al *AttributeResultList) String() string {
...@@ -541,62 +540,9 @@ func (al *AttributeResultList) String() string { ...@@ -541,62 +540,9 @@ func (al *AttributeResultList) String() string {
return str return str
} }
// Set the proof status to a new status for a specified attribute. An attribute is specified by an attributeTypeIdentifier
func (al *AttributeResultList) SetProofStatus(attrID AttributeTypeIdentifier, attrValue TranslatedString, status AttributeProofStatus) bool {
for _, ar := range al.AttributeResults {
// TODO: translation
if ar.AttributeId == attrID && ar.AttributeValue["en"] == attrValue["en"] {
ar.AttributeProofStatus = status
return true
}
}
return false
}
func (ar *AttributeResult) GetAttributeDescription(conf *Configuration) (*AttributeDescription, error) {
cred := conf.CredentialTypes[NewCredentialTypeIdentifier(ar.AttributeId.Parent())]
index, err := cred.IndexOf(ar.AttributeId)
if err != nil {
return nil, err
}
return &cred.Attributes[index], nil
}
func (ar *AttributeResult) String() string { func (ar *AttributeResult) String() string {
// TODO: translated string!
return fmt.Sprintf("%v --- %v --- %v", return fmt.Sprintf("%v --- %v --- %v",
ar.AttributeId, ar.AttributeId,
ar.AttributeValue["en"], ar.AttributeValue,
ar.AttributeProofStatus) ar.AttributeProofStatus)
} }
func AttributeResultListFromDisclosed(disclosed []*CredentialInfo, conf *Configuration) *AttributeResultList {
al := AttributeResultList{}
for _, cred := range disclosed {
credentialType := cred.GetCredentialType(conf)
for _, attr := range credentialType.Attributes {
attrId := NewAttributeTypeIdentifier(cred.CredentialTypeID.String() + "." + attr.ID)
index, err := credentialType.IndexOf(attrId)
if err != nil {
// Specified credential does not contain this attribute, move to next
break
}
disclosedAttributeValue := cred.Attributes[index]
if disclosedAttributeValue != nil {
al.Append(AttributeResult{
AttributeValue: disclosedAttributeValue,
AttributeId: attrId,
AttributeProofStatus: UNKNOWN,
})
}
}
}
return &al
}
...@@ -48,41 +48,6 @@ func NewCredentialInfo(ints []*big.Int, conf *Configuration) *CredentialInfo { ...@@ -48,41 +48,6 @@ func NewCredentialInfo(ints []*big.Int, conf *Configuration) *CredentialInfo {
} }
} }
// Convert proof responses to Ints, adding nils for undislosed attributes
func convertProofResponsesToInts(aResponses map[int]*big.Int, aDisclosed map[int]*big.Int) ([]*big.Int, error) {
var ints []*big.Int
length := len(aResponses) + len(aDisclosed)
for i := 1; i < length; i++ {
if aResponses[i] == nil {
if aDisclosed[i] == nil {
// If index not found in aResponses it must be in aDisclosed
return nil, &SessionError{
ErrorType: ErrorCrypto,
Info: fmt.Sprintf("Missing attribute index: %v", i),
} // TODO: error type?
}
ints = append(ints, aDisclosed[i])
} else {
// Don't include value of hidden attributes
ints = append(ints, nil)
}
}
return ints, nil
}
// NewAttributeListFromInts initializes a new AttributeList from disclosed attributes of a prooflist
func NewCredentialInfoFromADisclosed(aResponses map[int]*big.Int, aDisclosed map[int]*big.Int, conf *Configuration) (*CredentialInfo, error) {
ints, err := convertProofResponsesToInts(aResponses, aDisclosed)
if err != nil {
return nil, err
}
return NewCredentialInfo(ints, conf), nil
}
func (ci CredentialInfo) GetCredentialType(conf *Configuration) *CredentialType { func (ci CredentialInfo) GetCredentialType(conf *Configuration) *CredentialType {
return conf.CredentialTypes[ci.CredentialTypeID] return conf.CredentialTypes[ci.CredentialTypeID]
} }
......
...@@ -81,6 +81,10 @@ type AttributeDescription struct { ...@@ -81,6 +81,10 @@ type AttributeDescription struct {
Description TranslatedString Description TranslatedString
} }
func (ad AttributeDescription) GetAttributeTypeIdentifier(cred CredentialTypeIdentifier) AttributeTypeIdentifier {
return NewAttributeTypeIdentifier(cred.String() + "." + ad.ID)
}
// IndexOf returns the index of the specified attribute if present, // IndexOf returns the index of the specified attribute if present,
// or an error (and -1) if not present. // or an error (and -1) if not present.
func (ct CredentialType) IndexOf(ai AttributeTypeIdentifier) (int, error) { func (ct CredentialType) IndexOf(ai AttributeTypeIdentifier) (int, error) {
......
...@@ -10,17 +10,12 @@ import ( ...@@ -10,17 +10,12 @@ import (
"testing" "testing"
) )
type Result struct {
proofStatus ProofStatus
attributes *irma.AttributeResultList
}
type ManualSessionHandler struct { type ManualSessionHandler struct {
permissionHandler PermissionHandler permissionHandler PermissionHandler
pinHandler PinHandler pinHandler PinHandler
t *testing.T t *testing.T
errorChannel chan *irma.SessionError errorChannel chan *irma.SessionError
resultChannel chan Result resultChannel chan *irma.SignatureProofResult
sigRequest *irma.SignatureRequest // Request used to create signature sigRequest *irma.SignatureRequest // Request used to create signature
sigVerifyRequest *irma.SignatureRequest // Request used to verify signature sigVerifyRequest *irma.SignatureRequest // Request used to verify signature
} }
...@@ -56,7 +51,7 @@ func corruptProofString(proof string) string { ...@@ -56,7 +51,7 @@ func corruptProofString(proof string) string {
// Create a ManualSessionHandler for unit tests // Create a ManualSessionHandler for unit tests
func createManualSessionHandler(request string, invalidRequest string, t *testing.T) ManualSessionHandler { func createManualSessionHandler(request string, invalidRequest string, t *testing.T) ManualSessionHandler {
errorChannel := make(chan *irma.SessionError) errorChannel := make(chan *irma.SessionError)
resultChannel := make(chan Result) resultChannel := make(chan *irma.SignatureProofResult)
sigRequestJSON := []byte(request) sigRequestJSON := []byte(request)
invalidSigRequestJSON := []byte(invalidRequest) invalidSigRequestJSON := []byte(invalidRequest)
...@@ -90,11 +85,11 @@ func TestManualSession(t *testing.T) { ...@@ -90,11 +85,11 @@ func TestManualSession(t *testing.T) {
// No errors, obtain proof result from channel // No errors, obtain proof result from channel
result := <-ms.resultChannel result := <-ms.resultChannel
if ps := result.proofStatus; ps != VALID { if ps := result.ProofStatus; ps != irma.VALID {
t.Logf("Invalid proof result: %v Expected: %v", ps, VALID) t.Logf("Invalid proof result: %v Expected: %v", ps, irma.VALID)
t.Fail() t.Fail()
} }
if attrStatus := result.attributes.AttributeResults[0].AttributeProofStatus; attrStatus != irma.PRESENT { if attrStatus := result.ToAttributeResultList().AttributeResults[0].AttributeProofStatus; attrStatus != irma.PRESENT {
t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.PRESENT) t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.PRESENT)
t.Fail() t.Fail()
} }
...@@ -137,8 +132,8 @@ func TestManualSessionInvalidNonce(t *testing.T) { ...@@ -137,8 +132,8 @@ func TestManualSessionInvalidNonce(t *testing.T) {
} }
// No errors, obtain proof result from channel // No errors, obtain proof result from channel
if result := <-ms.resultChannel; result.proofStatus != INVALID_CRYPTO { if result := <-ms.resultChannel; result.ProofStatus != irma.INVALID_CRYPTO {
t.Logf("Invalid proof result: %v Expected: %v", result.proofStatus, INVALID_CRYPTO) t.Logf("Invalid proof result: %v Expected: %v", result.ProofStatus, irma.INVALID_CRYPTO)
t.Fail() t.Fail()
} }
test.ClearTestStorage(t) test.ClearTestStorage(t)
...@@ -163,18 +158,19 @@ func TestManualSessionInvalidRequest(t *testing.T) { ...@@ -163,18 +158,19 @@ func TestManualSessionInvalidRequest(t *testing.T) {
// No errors, obtain proof result from channel // No errors, obtain proof result from channel
result := <-ms.resultChannel result := <-ms.resultChannel
if ps := result.proofStatus; ps != MISSING_ATTRIBUTES { if ps := result.ProofStatus; ps != irma.MISSING_ATTRIBUTES {
t.Logf("Invalid proof result: %v Expected: %v", ps, MISSING_ATTRIBUTES) t.Logf("Invalid proof result: %v Expected: %v", ps, irma.MISSING_ATTRIBUTES)
t.Fail() t.Fail()
} }
// First attribute result is UNKOWN, since it is disclosed, but not matching the sigrequest
if attrStatus := result.attributes.AttributeResults[0].AttributeProofStatus; attrStatus != irma.UNKNOWN { // First attribute result is MISSING, because it is in the request but not disclosed
t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.UNKNOWN) if attrStatus := result.ToAttributeResultList().AttributeResults[0].AttributeProofStatus; attrStatus != irma.MISSING {
t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.MISSING)
t.Fail() t.Fail()
} }
// Second attribute result is MISSING, because it is in the request but not disclosed // Second attribute result is EXTRA, since it is disclosed, but not matching the sigrequest
if attrStatus := result.attributes.AttributeResults[1].AttributeProofStatus; attrStatus != irma.MISSING { if attrStatus := result.ToAttributeResultList().AttributeResults[1].AttributeProofStatus; attrStatus != irma.EXTRA {
t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.MISSING) t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.EXTRA)
t.Fail() t.Fail()
} }
test.ClearTestStorage(t) test.ClearTestStorage(t)
...@@ -199,11 +195,11 @@ func TestManualSessionInvalidAttributeValue(t *testing.T) { ...@@ -199,11 +195,11 @@ func TestManualSessionInvalidAttributeValue(t *testing.T) {
// No errors, obtain proof result from channel // No errors, obtain proof result from channel
result := <-ms.resultChannel result := <-ms.resultChannel
if ps := result.proofStatus; ps != MISSING_ATTRIBUTES { if ps := result.ProofStatus; ps != irma.MISSING_ATTRIBUTES {
t.Logf("Invalid proof result: %v Expected: %v", ps, MISSING_ATTRIBUTES) t.Logf("Invalid proof result: %v Expected: %v", ps, irma.MISSING_ATTRIBUTES)
t.Fail() t.Fail()
} }
if attrStatus := result.attributes.AttributeResults[0].AttributeProofStatus; attrStatus != irma.INVALID_VALUE { if attrStatus := result.ToAttributeResultList().AttributeResults[0].AttributeProofStatus; attrStatus != irma.INVALID_VALUE {
t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.INVALID_VALUE) t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.INVALID_VALUE)
t.Fail() t.Fail()
} }
...@@ -226,8 +222,8 @@ func TestManualKeyShareSession(t *testing.T) { ...@@ -226,8 +222,8 @@ func TestManualKeyShareSession(t *testing.T) {
} }
// No errors, obtain proof result from channel // No errors, obtain proof result from channel
if result := <-ms.resultChannel; result.proofStatus != VALID { if result := <-ms.resultChannel; result.ProofStatus != irma.VALID {
t.Logf("Invalid proof result: %v Expected: %v", result.proofStatus, VALID) t.Logf("Invalid proof result: %v Expected: %v", result.ProofStatus, irma.VALID)
t.Fail() t.Fail()
} }
test.ClearTestStorage(t) test.ClearTestStorage(t)
...@@ -258,8 +254,17 @@ func TestManualSessionMultiProof(t *testing.T) { ...@@ -258,8 +254,17 @@ func TestManualSessionMultiProof(t *testing.T) {
} }
// No errors, obtain proof result from channel // No errors, obtain proof result from channel
if result := <-ms.resultChannel; result.proofStatus != VALID { result := <-ms.resultChannel
t.Logf("Invalid proof result: %v Expected: %v", result.proofStatus, VALID) if ps := result.ProofStatus; ps != irma.VALID {
t.Logf("Invalid proof result: %v Expected: %v", result.ProofStatus, irma.VALID)
t.Fail()
}
if attrStatus := result.ToAttributeResultList().AttributeResults[0].AttributeProofStatus; attrStatus != irma.PRESENT {
t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.PRESENT)
t.Fail()
}
if attrStatus := result.ToAttributeResultList().AttributeResults[1].AttributeProofStatus; attrStatus != irma.PRESENT {
t.Logf("Invalid attribute result value: %v Expected: %v", attrStatus, irma.PRESENT)
t.Fail() t.Fail()
} }
test.ClearTestStorage(t) test.ClearTestStorage(t)
...@@ -280,8 +285,8 @@ func TestManualSessionInvalidProof(t *testing.T) { ...@@ -280,8 +285,8 @@ func TestManualSessionInvalidProof(t *testing.T) {
} }
// No errors, obtain proof result from channel // No errors, obtain proof result from channel
if result := <-ms.resultChannel; result.proofStatus != INVALID_CRYPTO { if result := <-ms.resultChannel; result.ProofStatus != irma.INVALID_CRYPTO {
t.Logf("Invalid proof result: %v Expected: %v", result.proofStatus, INVALID_CRYPTO) t.Logf("Invalid proof result: %v Expected: %v", result.ProofStatus, irma.INVALID_CRYPTO)
t.Fail() t.Fail()
} }
test.ClearTestStorage(t) test.ClearTestStorage(t)
...@@ -294,8 +299,7 @@ func (sh *ManualSessionHandler) Success(irmaAction irma.Action, result string) { ...@@ -294,8 +299,7 @@ func (sh *ManualSessionHandler) Success(irmaAction irma.Action, result string) {
result = corruptProofString(result) result = corruptProofString(result)
go func() { go func() {
proofStatus, attributeResultList := VerifySig(client.Configuration, result, sh.sigVerifyRequest) sh.resultChannel <- irma.VerifySig(client.Configuration, result, sh.sigVerifyRequest)
sh.resultChannel <- Result{proofStatus, attributeResultList}
}() }()
} }
sh.errorChannel <- nil sh.errorChannel <- nil
......
package irmaclient
import (
"fmt"
"github.com/go-errors/errors"
"github.com/mhe/gabi"
"github.com/privacybydesign/irmago"
"math/big"
)
// TODO: move to irma package?
type ProofResult struct {
proofStatus ProofStatus // The overall proofstatus, should be VALID in order to accept the proof
attributes []irma.AttributeResult
}
type ProofStatus string
const (
VALID = ProofStatus("VALID")
EXPIRED = ProofStatus("EXPIRED")
INVALID_CRYPTO = ProofStatus("INVALID_CRYPTO")
INVALID_JSON = ProofStatus("INVALID_JSON")
MISSING_ATTRIBUTES = ProofStatus("MISSING_ATTRIBUTES")
)
func extractPublicKeys(configuration *irma.Configuration, proofList *gabi.ProofList) ([]*gabi.PublicKey, error) {
var publicKeys []*gabi.PublicKey
for _, v := range *proofList {
switch v.(type) {
case *gabi.ProofD:
proof := v.(*gabi.ProofD)
metadata := irma.MetadataFromInt(proof.ADisclosed[1], configuration) // index 1 is metadata attribute
publicKey, err := metadata.PublicKey()
if err != nil {
return nil, err
}
publicKeys = append(publicKeys, publicKey)
default:
return nil, errors.New("Cannot extract public key, not a disclosure proofD!")
}
}
return publicKeys, nil
}