Commit ff181fcb authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Move functions across files

parent 3f4c5d6c
...@@ -163,7 +163,7 @@ func HandleProtocolMessage( ...@@ -163,7 +163,7 @@ func HandleProtocolMessage(
} }
} }
if method == "GET" && verb == "status" { if method == "GET" && verb == "status" {
status, output = responseJson(handleGetStatus(session), nil) status, output = responseJson(session.handleGetStatus(), nil)
return return
} }
status, output = responseJson(nil, session.fail(irmaserver.ErrorInvalidRequest, "")) status, output = responseJson(nil, session.fail(irmaserver.ErrorInvalidRequest, ""))
......
package backend package backend
import ( import (
"encoding/json"
"net/http"
"runtime/debug"
"time"
"github.com/mhe/gabi" "github.com/mhe/gabi"
"github.com/privacybydesign/irmago" "github.com/privacybydesign/irmago"
"github.com/privacybydesign/irmago/irmaserver" "github.com/privacybydesign/irmago/irmaserver"
) )
// This file contains the handler functions for the protocol messages, receiving and returning normally
// Go-typed messages here (JSON (un)marshalling is handled by the router).
// Maintaining the session state is done here, as well as checking whether the session is in the
// appropriate status before handling the request.
var conf *irmaserver.Configuration var conf *irmaserver.Configuration
func (session *session) handleDelete() { func (session *session) handleDelete() {
...@@ -18,6 +18,7 @@ func (session *session) handleDelete() { ...@@ -18,6 +18,7 @@ func (session *session) handleDelete() {
return return
} }
session.markAlive() session.markAlive()
// TODO const ProofStatusCancelled = irma.ProofStatus("CANCELLED") ? // TODO const ProofStatusCancelled = irma.ProofStatus("CANCELLED") ?
session.result = &irmaserver.SessionResult{Token: session.token} session.result = &irmaserver.SessionResult{Token: session.token}
session.setStatus(irmaserver.StatusCancelled) session.setStatus(irmaserver.StatusCancelled)
...@@ -39,7 +40,7 @@ func (session *session) handleGetRequest(min, max *irma.ProtocolVersion) (irma.S ...@@ -39,7 +40,7 @@ func (session *session) handleGetRequest(min, max *irma.ProtocolVersion) (irma.S
return session.request, nil return session.request, nil
} }
func handleGetStatus(session *session) irmaserver.Status { func (session *session) handleGetStatus() irmaserver.Status {
return session.status return session.status
} }
...@@ -68,52 +69,68 @@ func (session *session) handlePostProofs(proofs gabi.ProofList) (*irma.ProofStat ...@@ -68,52 +69,68 @@ func (session *session) handlePostProofs(proofs gabi.ProofList) (*irma.ProofStat
return &session.result.Status, nil return &session.result.Status, nil
} }
// Session helpers func (session *session) handlePostCommitments(commitments *gabi.IssueCommitmentMessage) ([]*gabi.IssueSignatureMessage, *irma.RemoteError) {
if session.status != irmaserver.StatusConnected {
func (session *session) finished() bool { return nil, getError(irmaserver.ErrorUnexpectedRequest, "Session not yet started or already finished")
return session.status == irmaserver.StatusDone || session.status == irmaserver.StatusCancelled }
} session.markAlive()
func (session *session) markAlive() {
session.lastActive = time.Now()
}
func (session *session) setStatus(status irmaserver.Status) { request := session.request.(*irma.IssuanceRequest)
session.status = status discloseCount := len(request.Disclose)
} if len(commitments.Proofs) != len(request.Credentials)+discloseCount {
return nil, session.fail(irmaserver.ErrorAttributesMissing, "")
}
func (session *session) fail(err irmaserver.Error, message string) *irma.RemoteError { // Compute list of public keys against which to verify the received proofs
rerr := getError(err, message) disclosureproofs := irma.ProofList(commitments.Proofs[:discloseCount])
session.setStatus(irmaserver.StatusCancelled) pubkeys, err := disclosureproofs.ExtractPublicKeys(conf.IrmaConfiguration)
session.result = &irmaserver.SessionResult{Err: rerr, Token: session.token} if err != nil {
return rerr return nil, session.fail(irmaserver.ErrorInvalidProofs, err.Error())
} }
for _, cred := range request.Credentials {
iss := cred.CredentialTypeID.IssuerIdentifier()
pubkey, _ := conf.IrmaConfiguration.PublicKey(iss, cred.KeyCounter) // No error, already checked earlier
pubkeys = append(pubkeys, pubkey)
}
// Output helpers // Verify and merge keyshare server proofs, if any
for i, proof := range commitments.Proofs {
func getError(err irmaserver.Error, message string) *irma.RemoteError { pubkey := pubkeys[i]
stack := string(debug.Stack()) schemeid := irma.NewIssuerIdentifier(pubkey.Issuer).SchemeManagerIdentifier()
conf.Logger.Errorf("Error: %d %s %s\n%s", err.Status, err.Type, message, stack) if conf.IrmaConfiguration.SchemeManagers[schemeid].Distributed() {
return &irma.RemoteError{ proofP, err := session.getProofP(commitments, schemeid)
Status: err.Status, if err != nil {
Description: err.Description, return nil, session.fail(irmaserver.ErrorKeyshareProofMissing, err.Error())
ErrorName: string(err.Type), }
Message: message, proof.MergeProofP(proofP, pubkey)
Stacktrace: stack, }
} }
}
func responseJson(v interface{}, err *irma.RemoteError) (int, []byte) { // Verify all proofs and check disclosed attributes, if any, against request
msg := v session.result.Disclosed, session.result.Status = irma.ProofList(commitments.Proofs).VerifyAgainstDisjunctions(
status := http.StatusOK conf.IrmaConfiguration, request.Disclose, request.Context, request.Nonce, pubkeys, false)
if err != nil { if session.result.Status != irma.ProofStatusValid {
msg = err return nil, session.fail(irmaserver.ErrorInvalidProofs, "")
status = err.Status
} }
b, e := json.Marshal(msg)
if e != nil { // Compute CL signatures
conf.Logger.Error("Failed to serialize response:", e.Error()) var sigs []*gabi.IssueSignatureMessage
return http.StatusInternalServerError, nil for i, cred := range request.Credentials {
id := cred.CredentialTypeID.IssuerIdentifier()
pk, _ := conf.IrmaConfiguration.PublicKey(id, cred.KeyCounter)
issuer := gabi.NewIssuer(conf.PrivateKeys[id], pk, one)
proof := commitments.Proofs[i+discloseCount].(*gabi.ProofU)
attributes, err := cred.AttributeList(conf.IrmaConfiguration, 0x03)
if err != nil {
return nil, session.fail(irmaserver.ErrorUnknown, err.Error())
}
sig, err := issuer.IssueSignature(proof.U, attributes.Ints, commitments.Nonce2)
if err != nil {
return nil, session.fail(irmaserver.ErrorUnknown, err.Error())
}
sigs = append(sigs, sig)
} }
return status, b
session.setStatus(irmaserver.StatusDone)
return sigs, nil
} }
package backend package backend
import ( import (
"encoding/json"
"fmt" "fmt"
"net/http"
"runtime/debug"
"strconv" "strconv"
"time" "time"
...@@ -12,6 +15,58 @@ import ( ...@@ -12,6 +15,58 @@ import (
"github.com/privacybydesign/irmago/irmaserver" "github.com/privacybydesign/irmago/irmaserver"
) )
// Session helpers
func (session *session) finished() bool {
return session.status == irmaserver.StatusDone || session.status == irmaserver.StatusCancelled
}
func (session *session) markAlive() {
session.lastActive = time.Now()
}
func (session *session) setStatus(status irmaserver.Status) {
session.status = status
}
func (session *session) fail(err irmaserver.Error, message string) *irma.RemoteError {
rerr := getError(err, message)
session.setStatus(irmaserver.StatusCancelled)
session.result = &irmaserver.SessionResult{Err: rerr, Token: session.token}
return rerr
}
// Output helpers
func getError(err irmaserver.Error, message string) *irma.RemoteError {
stack := string(debug.Stack())
conf.Logger.Errorf("Error: %d %s %s\n%s", err.Status, err.Type, message, stack)
return &irma.RemoteError{
Status: err.Status,
Description: err.Description,
ErrorName: string(err.Type),
Message: message,
Stacktrace: stack,
}
}
func responseJson(v interface{}, err *irma.RemoteError) (int, []byte) {
msg := v
status := http.StatusOK
if err != nil {
msg = err
status = err.Status
}
b, e := json.Marshal(msg)
if e != nil {
conf.Logger.Error("Failed to serialize response:", e.Error())
return http.StatusInternalServerError, nil
}
return status, b
}
// Issuance helpers
func validateIssuanceRequest(request *irma.IssuanceRequest) error { func validateIssuanceRequest(request *irma.IssuanceRequest) error {
for _, cred := range request.Credentials { for _, cred := range request.Credentials {
// Check that we have the appropriate private key // Check that we have the appropriate private key
...@@ -83,68 +138,15 @@ func (session *session) getProofP(commitments *gabi.IssueCommitmentMessage, sche ...@@ -83,68 +138,15 @@ func (session *session) getProofP(commitments *gabi.IssueCommitmentMessage, sche
return session.kssProofs[scheme], nil return session.kssProofs[scheme], nil
} }
func (session *session) handlePostCommitments(commitments *gabi.IssueCommitmentMessage) ([]*gabi.IssueSignatureMessage, *irma.RemoteError) { // Other
if session.status != irmaserver.StatusConnected {
return nil, getError(irmaserver.ErrorUnexpectedRequest, "Session not yet started or already finished")
}
session.markAlive()
request := session.request.(*irma.IssuanceRequest) func chooseProtocolVersion(min, max *irma.ProtocolVersion) (*irma.ProtocolVersion, error) {
discloseCount := len(request.Disclose) if min.AboveVersion(minProtocolVersion) || max.BelowVersion(min) {
if len(commitments.Proofs) != len(request.Credentials)+discloseCount { return nil, errors.Errorf("Protocol version negotiation failed, min=%s max=%s", min.String(), max.String())
return nil, session.fail(irmaserver.ErrorAttributesMissing, "")
} }
if max.AboveVersion(maxProtocolVersion) {
// Compute list of public keys against which to verify the received proofs return maxProtocolVersion, nil
disclosureproofs := irma.ProofList(commitments.Proofs[:discloseCount]) } else {
pubkeys, err := disclosureproofs.ExtractPublicKeys(conf.IrmaConfiguration) return max, nil
if err != nil {
return nil, session.fail(irmaserver.ErrorInvalidProofs, err.Error())
}
for _, cred := range request.Credentials {
iss := cred.CredentialTypeID.IssuerIdentifier()
pubkey, _ := conf.IrmaConfiguration.PublicKey(iss, cred.KeyCounter) // No error, already checked earlier
pubkeys = append(pubkeys, pubkey)
}
// Verify and merge keyshare server proofs, if any
for i, proof := range commitments.Proofs {
pubkey := pubkeys[i]
schemeid := irma.NewIssuerIdentifier(pubkey.Issuer).SchemeManagerIdentifier()
if conf.IrmaConfiguration.SchemeManagers[schemeid].Distributed() {
proofP, err := session.getProofP(commitments, schemeid)
if err != nil {
return nil, session.fail(irmaserver.ErrorKeyshareProofMissing, err.Error())
}
proof.MergeProofP(proofP, pubkey)
}
} }
// Verify all proofs and check disclosed attributes, if any, against request
session.result.Disclosed, session.result.Status = irma.ProofList(commitments.Proofs).VerifyAgainstDisjunctions(
conf.IrmaConfiguration, request.Disclose, request.Context, request.Nonce, pubkeys, false)
if session.result.Status != irma.ProofStatusValid {
return nil, session.fail(irmaserver.ErrorInvalidProofs, "")
}
// Compute CL signatures
var sigs []*gabi.IssueSignatureMessage
for i, cred := range request.Credentials {
id := cred.CredentialTypeID.IssuerIdentifier()
pk, _ := conf.IrmaConfiguration.PublicKey(id, cred.KeyCounter)
issuer := gabi.NewIssuer(conf.PrivateKeys[id], pk, one)
proof := commitments.Proofs[i+discloseCount].(*gabi.ProofU)
attributes, err := cred.AttributeList(conf.IrmaConfiguration, 0x03)
if err != nil {
return nil, session.fail(irmaserver.ErrorUnknown, err.Error())
}
sig, err := issuer.IssueSignature(proof.U, attributes.Ints, commitments.Nonce2)
if err != nil {
return nil, session.fail(irmaserver.ErrorUnknown, err.Error())
}
sigs = append(sigs, sig)
}
session.setStatus(irmaserver.StatusDone)
return sigs, nil
} }
...@@ -6,7 +6,6 @@ import ( ...@@ -6,7 +6,6 @@ import (
"sync" "sync"
"time" "time"
"github.com/go-errors/errors"
"github.com/mhe/gabi" "github.com/mhe/gabi"
"github.com/privacybydesign/irmago" "github.com/privacybydesign/irmago"
"github.com/privacybydesign/irmago/irmaserver" "github.com/privacybydesign/irmago/irmaserver"
...@@ -125,14 +124,3 @@ func newSessionToken() string { ...@@ -125,14 +124,3 @@ func newSessionToken() string {
} }
return string(b) return string(b)
} }
func chooseProtocolVersion(min, max *irma.ProtocolVersion) (*irma.ProtocolVersion, error) {
if min.AboveVersion(minProtocolVersion) || max.BelowVersion(min) {
return nil, errors.Errorf("Protocol version negotiation failed, min=%s max=%s", min.String(), max.String())
}
if max.AboveVersion(maxProtocolVersion) {
return maxProtocolVersion, nil
} else {
return max, nil
}
}
Supports Markdown
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