Commit b1129984 authored by Sietse Ringers's avatar Sietse Ringers

feat: new ABS timestamp format compatible with future extensions of credential types

parent cedac54e
......@@ -20,6 +20,9 @@ type SignedMessage struct {
Context *big.Int `json:"context"`
Message string `json:"message"`
Timestamp *atum.Timestamp `json:"timestamp"`
// Message version. Current version is 2.
Version int `json:"v,omitempty"`
}
func (sm *SignedMessage) GetNonce() *big.Int {
......
......@@ -568,7 +568,7 @@ func (client *Client) ProofBuilders(choice *irma.DisclosureChoice, request irma.
disclosed = append(disclosed, d)
}
r := request.(*irma.SignatureRequest)
r.Timestamp, err = irma.GetTimestamp(r.Message, sigs, disclosed)
r.Timestamp, err = irma.GetTimestamp(r.Message, sigs, disclosed, client.Configuration)
if err != nil {
return nil, nil, err
}
......
......@@ -23,6 +23,7 @@ type LogEntry struct {
Removed map[irma.CredentialTypeIdentifier][]irma.TranslatedString `json:",omitempty"` // In case of credential removal
SignedMessage []byte `json:",omitempty"` // In case of signature sessions
Timestamp *atum.Timestamp `json:",omitempty"` // In case of signature sessions
SignatureVersion int `json:",omitempty"` // In case of signature sessions
IssueCommitment *irma.IssueCommitmentMessage `json:",omitempty"`
Disclosure *irma.Disclosure `json:",omitempty"`
......@@ -110,6 +111,7 @@ func (entry *LogEntry) GetSignedMessage() (abs *irma.SignedMessage, err error) {
Context: sigrequest.Context,
Message: string(entry.SignedMessage),
Timestamp: entry.Timestamp,
Version: entry.SignatureVersion,
}, nil
}
......@@ -133,6 +135,7 @@ func (session *session) createLogEntry(response interface{}) (*LogEntry, error)
request := session.request.(*irma.SignatureRequest)
entry.SignedMessage = []byte(request.Message)
entry.Timestamp = request.Timestamp
entry.SignatureVersion = 2
fallthrough
case irma.ActionDisclosing:
......
......@@ -439,6 +439,7 @@ func (sr *SignatureRequest) SignatureFromMessage(message interface{}) (*SignedMe
Context: sr.Context,
Message: sr.Message,
Timestamp: sr.Timestamp,
Version: 2,
}, nil
}
......
......@@ -3,10 +3,10 @@ package irma
import (
"crypto/sha256"
"encoding/asn1"
"errors"
gobig "math/big"
"github.com/bwesterb/go-atum"
"github.com/go-errors/errors"
"github.com/privacybydesign/gabi"
"github.com/privacybydesign/gabi/big"
)
......@@ -14,8 +14,8 @@ import (
// GetTimestamp GETs a signed timestamp (a signature over the current time and the parameters)
// over the message to be signed, the randomized signatures over the attributes, and the disclosed
// attributes, for in attribute-based signature sessions.
func GetTimestamp(message string, sigs []*big.Int, disclosed [][]*big.Int) (*atum.Timestamp, error) {
nonce, err := TimestampRequest(message, sigs, disclosed)
func GetTimestamp(message string, sigs []*big.Int, disclosed [][]*big.Int, conf *Configuration) (*atum.Timestamp, error) {
nonce, err := TimestampRequest(message, sigs, disclosed, true, conf)
if err != nil {
return nil, err
}
......@@ -26,30 +26,51 @@ func GetTimestamp(message string, sigs []*big.Int, disclosed [][]*big.Int) (*atu
})
}
var bigZero = big.NewInt(0)
// TimestampRequest computes the nonce to be signed by a timestamp server, given a message to be signed
// in an attribute-based signature session along with the randomized signatures over the attributes
// and the disclosed attributes.
func TimestampRequest(message string, sigs []*big.Int, disclosed [][]*big.Int) ([]byte, error) {
func TimestampRequest(message string, sigs []*big.Int, disclosed [][]*big.Int, new bool, conf *Configuration) ([]byte, error) {
msgHash := sha256.Sum256([]byte(message))
// Convert the sigs and disclosed (double) slices to (double) slices of gobig.Int's for asn1
sigsint := make([]*gobig.Int, len(sigs))
disclosedint := make([][]*gobig.Int, len(disclosed))
for i, k := range sigs {
sigsint[i] = k.Value()
}
disclosedint := make([][]*gobig.Int, len(disclosed))
dlreps := make([]*gobig.Int, len(disclosed))
var d interface{} = disclosedint
for i, _ := range disclosed {
if !new {
disclosedint[i] = make([]*gobig.Int, len(disclosed[i]))
for j, k := range disclosed[i] {
disclosedint[i][j] = k.Value()
}
} else {
if len(disclosed[i]) < 2 || disclosed[i][1].Cmp(bigZero) == 0 {
return nil, errors.Errorf("metadata attribute of credential %d not disclosed", i)
}
meta := MetadataFromInt(disclosed[i][1], conf)
pk, err := conf.PublicKey(meta.CredentialType().IssuerIdentifier(), meta.KeyCounter())
if err != nil {
return nil, err
}
dlreps[i] = gabi.RepresentToPublicKey(pk, disclosed[i]).Value()
}
}
if new {
d = dlreps
}
bts, err := asn1.Marshal(struct {
Sigs []*gobig.Int
MsgHash []byte
Disclosed [][]*gobig.Int
Disclosed interface{}
}{
sigsint, msgHash[:], disclosedint,
sigsint, msgHash[:], d,
})
if err != nil {
return nil, err
......@@ -93,7 +114,7 @@ func (sm *SignedMessage) VerifyTimestamp(message string, conf *Configuration) er
}
}
bts, err := TimestampRequest(message, sigs, disclosed)
bts, err := TimestampRequest(message, sigs, disclosed, sm.Version >= 2, conf)
if err != nil {
return 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