requests.go 26.6 KB
Newer Older
1
package irma
2
3

import (
4
	"encoding/json"
5
	"fmt"
6
	"io/ioutil"
7
8
9
	"strconv"
	"time"

10
	"github.com/bwesterb/go-atum"
11
	"github.com/dgrijalva/jwt-go"
Sietse Ringers's avatar
Sietse Ringers committed
12
	"github.com/go-errors/errors"
13
	"github.com/privacybydesign/gabi"
14
	"github.com/privacybydesign/gabi/big"
15
	"github.com/privacybydesign/irmago/internal/fs"
Sietse Ringers's avatar
Sietse Ringers committed
16
)
17

18
19
20
21
22
23
const (
	LDContextDisclosureRequest = "https://irma.app/ld/request/disclosure/v2"
	LDContextSignatureRequest  = "https://irma.app/ld/request/signature/v2"
	LDContextIssuanceRequest   = "https://irma.app/ld/request/issuance/v2"
)

24
25
// BaseRequest contains the context and nonce for an IRMA session.
type BaseRequest struct {
26
	LDContext string `json:"@context,omitempty"`
27

28
	// Chosen by the IRMA server during the session
29
30
31
	Context         *big.Int         `json:"context,omitempty"`
	Nonce           *big.Int         `json:"nonce,omitempty"`
	ProtocolVersion *ProtocolVersion `json:"protocolVersion,omitempty"`
32

33
34
35
36
	ids *IrmaIdentifierSet // cache for Identifiers() method

	legacy bool   // Whether or not this was deserialized from a legacy (pre-condiscon) request
	Type   Action `json:"type,omitempty"` // Session type, only used in legacy code
37
38

	ClientReturnURL string `json:"clientReturnUrl,omitempty"` // URL to proceed to when IRMA session is completed
Sietse Ringers's avatar
Sietse Ringers committed
39
40
}

41
42
// An AttributeCon is only satisfied if all of its containing attribute requests are satisfied.
type AttributeCon []AttributeRequest
43

44
45
// An AttributeDisCon is satisfied if at least one of its containing AttributeCon is satisfied.
type AttributeDisCon []AttributeCon
46

47
48
// AttributeConDisCon is only satisfied if all of the containing AttributeDisCon are satisfied.
type AttributeConDisCon []AttributeDisCon
49

50
51
// A DisclosureRequest is a request to disclose certain attributes. Construct new instances using
// NewDisclosureRequest().
52
type DisclosureRequest struct {
53
	BaseRequest
54

55
56
	Disclose AttributeConDisCon       `json:"disclose,omitempty"`
	Labels   map[int]TranslatedString `json:"labels,omitempty"`
57
58
}

59
60
// A SignatureRequest is a a request to sign a message with certain attributes. Construct new
// instances using NewSignatureRequest().
61
type SignatureRequest struct {
62
	DisclosureRequest
63
	Message string `json:"message"`
64
65
}

Sietse Ringers's avatar
Sietse Ringers committed
66
// An IssuanceRequest is a request to issue certain credentials,
67
68
// optionally also asking for certain attributes to be simultaneously disclosed. Construct new
// instances using NewIssuanceRequest().
69
type IssuanceRequest struct {
70
	DisclosureRequest
71
	Credentials []*CredentialRequest `json:"credentials"`
Tomas's avatar
Tomas committed
72
73
74

	// Derived data
	CredentialInfoList        CredentialInfoList `json:",omitempty"`
75
	RemovalCredentialInfoList CredentialInfoList `json:",omitempty"`
76
77
}

Sietse Ringers's avatar
Sietse Ringers committed
78
79
// A CredentialRequest contains the attributes and metadata of a credential
// that will be issued in an IssuanceRequest.
80
type CredentialRequest struct {
81
82
	Validity         *Timestamp               `json:"validity,omitempty"`
	KeyCounter       int                      `json:"keyCounter,omitempty"`
83
84
	CredentialTypeID CredentialTypeIdentifier `json:"credential"`
	Attributes       map[string]string        `json:"attributes"`
Sietse Ringers's avatar
Sietse Ringers committed
85
86
}

87
88
89
90
// SessionRequest instances contain all information the irmaclient needs to perform an IRMA session.
type SessionRequest interface {
	Validator
	Base() *BaseRequest
91
	GetNonce(timestamp *atum.Timestamp) *big.Int
92
93
94
	Disclosure() *DisclosureRequest
	Identifiers() *IrmaIdentifierSet
	Action() Action
95
	Legacy() (SessionRequest, error)
96
97
98
99
100
}

// Timestamp is a time.Time that marshals to Unix timestamps.
type Timestamp time.Time

Sietse Ringers's avatar
Sietse Ringers committed
101
102
103
104
105
106
107
// ServerJwt contains standard JWT fields.
type ServerJwt struct {
	Type       string    `json:"sub"`
	ServerName string    `json:"iss"`
	IssuedAt   Timestamp `json:"iat"`
}

108
109
// RequestorBaseRequest contains fields present in all RequestorRequest types
// with which the requestor configures an IRMA session.
110
type RequestorBaseRequest struct {
Sietse Ringers's avatar
Sietse Ringers committed
111
112
	ResultJwtValidity int    `json:"validity,omitempty"`    // Validity of session result JWT in seconds
	ClientTimeout     int    `json:"timeout,omitempty"`     // Wait this many seconds for the IRMA app to connect before the session times out
113
	CallbackURL       string `json:"callbackUrl,omitempty"` // URL to post session result to
114
115
}

116
117
// RequestorRequest is the message with which requestors start an IRMA session. It contains a
// SessionRequest instance for the irmaclient along with extra fields in a RequestorBaseRequest.
118
119
120
type RequestorRequest interface {
	Validator
	SessionRequest() SessionRequest
121
	Base() RequestorBaseRequest
122
123
}

Sietse Ringers's avatar
Sietse Ringers committed
124
125
// A ServiceProviderRequest contains a disclosure request.
type ServiceProviderRequest struct {
126
	RequestorBaseRequest
Sietse Ringers's avatar
Sietse Ringers committed
127
128
129
130
131
	Request *DisclosureRequest `json:"request"`
}

// A SignatureRequestorRequest contains a signing request.
type SignatureRequestorRequest struct {
132
	RequestorBaseRequest
Sietse Ringers's avatar
Sietse Ringers committed
133
134
135
136
137
	Request *SignatureRequest `json:"request"`
}

// An IdentityProviderRequest contains an issuance request.
type IdentityProviderRequest struct {
138
	RequestorBaseRequest
Sietse Ringers's avatar
Sietse Ringers committed
139
140
141
142
143
144
	Request *IssuanceRequest `json:"request"`
}

// ServiceProviderJwt is a requestor JWT for a disclosure session.
type ServiceProviderJwt struct {
	ServerJwt
145
	Request *ServiceProviderRequest `json:"sprequest"`
Sietse Ringers's avatar
Sietse Ringers committed
146
147
148
149
150
}

// SignatureRequestorJwt is a requestor JWT for a signing session.
type SignatureRequestorJwt struct {
	ServerJwt
151
	Request *SignatureRequestorRequest `json:"absrequest"`
Sietse Ringers's avatar
Sietse Ringers committed
152
153
154
155
156
}

// IdentityProviderJwt is a requestor JWT for issuance session.
type IdentityProviderJwt struct {
	ServerJwt
157
158
159
	Request *IdentityProviderRequest `json:"iprequest"`
}

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// A RequestorJwt contains an IRMA session object.
type RequestorJwt interface {
	Action() Action
	RequestorRequest() RequestorRequest
	SessionRequest() SessionRequest
	Requestor() string
	Valid() error
	Sign(jwt.SigningMethod, interface{}) (string, error)
}

// A DisclosureChoice contains the attributes chosen to be disclosed.
type DisclosureChoice struct {
	Attributes [][]*AttributeIdentifier
}

// An AttributeRequest asks for an instance of an attribute type, possibly requiring it to have
// a specified value, in a session request.
type AttributeRequest struct {
178
179
180
	Type    AttributeTypeIdentifier `json:"type"`
	Value   *string                 `json:"value,omitempty"`
	NotNull bool                    `json:"notNull,omitempty"`
181
182
183
184
185
186
187
}

var (
	bigZero = big.NewInt(0)
	bigOne  = big.NewInt(1)
)

188
189
190
191
func (b *BaseRequest) Legacy() bool {
	return b.legacy
}

192
193
194
func (b *BaseRequest) GetContext() *big.Int {
	if b.Context == nil {
		return bigOne
195
	}
196
	return b.Context
197
198
}

199
func (b *BaseRequest) GetNonce(*atum.Timestamp) *big.Int {
200
201
	if b.Nonce == nil {
		return bigZero
202
	}
203
	return b.Nonce
204
205
}

206
207
208
// CredentialTypes returns an array of all credential types occuring in this conjunction.
func (c AttributeCon) CredentialTypes() []CredentialTypeIdentifier {
	var result []CredentialTypeIdentifier
209

210
	for _, attr := range c {
211
212
213
214
		typ := attr.Type.CredentialTypeIdentifier()
		if len(result) == 0 || result[len(result)-1] != typ {
			result = append(result, typ)
		}
215
	}
216

217
	return result
218
219
}

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
func (c AttributeCon) Validate() error {
	// Unlike AttributeDisCon, we don't have to check here that the current instance is of length 0,
	// as that is actually a valid conjunction: one that specifies that the containing disjunction
	// is optional.

	credtypes := map[CredentialTypeIdentifier]struct{}{}
	var last CredentialTypeIdentifier
	for _, attr := range c {
		typ := attr.Type.CredentialTypeIdentifier()
		if _, contains := credtypes[typ]; contains && last != typ {
			return errors.New("Within inner conjunctions, attributes from the same credential type must be adjacent")
		}
		last = typ
		credtypes[typ] = struct{}{}
	}
	return nil
}

238
239
// AttributeRequest synonym with default JSON (un)marshaler
type jsonAttributeRequest AttributeRequest
240

241
242
func (ar *AttributeRequest) UnmarshalJSON(bts []byte) error {
	var s AttributeTypeIdentifier
243

244
245
246
	// first try to parse as JSON string into s
	if err := json.Unmarshal(bts, &s); err == nil {
		*ar = AttributeRequest{Type: s}
247
248
249
		return nil
	}

250
251
	return json.Unmarshal(bts, (*jsonAttributeRequest)(ar))
}
252

253
func (ar *AttributeRequest) MarshalJSON() ([]byte, error) {
254
	if !ar.NotNull && ar.Value == nil {
255
		return json.Marshal(ar.Type)
256
	}
257
	return json.Marshal((*jsonAttributeRequest)(ar))
258
259
}

260
// Satisfy indicates whether the given attribute type and value satisfies this AttributeRequest.
261
func (ar *AttributeRequest) Satisfy(attr AttributeTypeIdentifier, val *string) bool {
262
	return ar.Type == attr &&
263
		(!ar.NotNull || val != nil) &&
264
		(ar.Value == nil || (val != nil && *ar.Value == *val))
Sietse Ringers's avatar
Sietse Ringers committed
265
266
}

267
268
// Satisfy returns if each of the attributes specified by proofs and indices satisfies each of
// the contained AttributeRequests's. If so it also returns a list of the disclosed attribute values.
269
func (c AttributeCon) Satisfy(proofs gabi.ProofList, indices []*DisclosedAttributeIndex, conf *Configuration) (bool, []*DisclosedAttribute, error) {
270
	if len(indices) < len(c) {
271
		return false, nil, nil
272
273
	}
	attrs := make([]*DisclosedAttribute, 0, len(c))
274
275
276
	if len(c) == 0 {
		return true, attrs, nil
	}
277
278
279
280
281

	for j := range c {
		index := indices[j]
		attr, val, err := extractAttribute(proofs, index, conf)
		if err != nil {
282
			return false, nil, err
283
284
		}
		if !c[j].Satisfy(attr.Identifier, val) {
285
			return false, nil, nil
286
287
288
		}
		attrs = append(attrs, attr)
	}
289
	return true, attrs, nil
290
291
}

292
293
294
295
296
297
298
299
300
301
302
303
304
func (dc AttributeDisCon) Validate() error {
	if len(dc) == 0 {
		return errors.New("Empty disjunction")
	}
	var err error
	for _, con := range dc {
		if err = con.Validate(); err != nil {
			return err
		}
	}
	return nil
}

305
306
// Satisfy returns true if the attributes specified by proofs and indices satisfies any one of the
// contained AttributeCon's. If so it also returns a list of the disclosed attribute values.
307
func (dc AttributeDisCon) Satisfy(proofs gabi.ProofList, indices []*DisclosedAttributeIndex, conf *Configuration) (bool, []*DisclosedAttribute, error) {
308
	for _, con := range dc {
309
310
311
		satisfied, attrs, err := con.Satisfy(proofs, indices, conf)
		if satisfied || err != nil {
			return true, attrs, err
312
313
		}
	}
314
	return false, nil, nil
315
316
}

317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
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
}

336
337
// Satisfy returns true if each of the contained AttributeDisCon is satisfied by the specified disclosure.
// If so it also returns the disclosed attributes.
338
339
340
341
342
343
344
345
func (cdc AttributeConDisCon) Satisfy(disclosure *Disclosure, conf *Configuration) (bool, [][]*DisclosedAttribute, error) {
	if len(disclosure.Indices) < len(cdc) {
		return false, nil, nil
	}
	list := make([][]*DisclosedAttribute, len(cdc))
	complete := true

	for i, discon := range cdc {
346
		satisfied, attrs, err := discon.Satisfy(disclosure.Proofs, disclosure.Indices[i], conf)
347
348
349
		if err != nil {
			return false, nil, err
		}
350
		if satisfied {
351
352
353
354
355
356
357
358
			list[i] = attrs
		} else {
			complete = false
			list[i] = nil
		}
	}

	return complete, list, nil
359
360
}

361
362
363
364
365
366
367
368
369
370
371
372
func (cdc AttributeConDisCon) Iterate(f func(attr *AttributeRequest) error) error {
	var err error
	for _, discon := range cdc {
		for _, con := range discon {
			for _, attr := range con {
				if err = f(&attr); err != nil {
					return err
				}
			}
		}
	}
	return nil
373
374
}

375
376
377
378
379
380
381
func (dr *DisclosureRequest) AddSingle(attr AttributeTypeIdentifier, value *string, label TranslatedString) {
	dr.Disclose = append(dr.Disclose, AttributeDisCon{AttributeCon{{Type: attr, Value: value}}})
	dr.Labels[len(dr.Disclose)-1] = label
}

func NewDisclosureRequest(attrs ...AttributeTypeIdentifier) *DisclosureRequest {
	request := &DisclosureRequest{
382
		BaseRequest: BaseRequest{LDContext: LDContextDisclosureRequest},
383
384
385
386
387
388
389
390
391
392
		Labels:      map[int]TranslatedString{},
	}
	for _, attr := range attrs {
		request.AddSingle(attr, nil, nil)
	}
	return request
}

func NewSignatureRequest(message string, attrs ...AttributeTypeIdentifier) *SignatureRequest {
	dr := NewDisclosureRequest(attrs...)
393
	dr.LDContext = LDContextSignatureRequest
394
	return &SignatureRequest{
395
		DisclosureRequest: *dr,
396
397
398
399
400
401
		Message:           message,
	}
}

func NewIssuanceRequest(creds []*CredentialRequest, attrs ...AttributeTypeIdentifier) *IssuanceRequest {
	dr := NewDisclosureRequest(attrs...)
402
	dr.LDContext = LDContextIssuanceRequest
403
	return &IssuanceRequest{
404
		DisclosureRequest: *dr,
405
406
407
408
409
410
411
412
		Credentials:       creds,
	}
}

func (dr *DisclosureRequest) Disclosure() *DisclosureRequest {
	return dr
}

413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
func (dr *DisclosureRequest) identifiers() *IrmaIdentifierSet {
	ids := &IrmaIdentifierSet{
		SchemeManagers:  map[SchemeManagerIdentifier]struct{}{},
		Issuers:         map[IssuerIdentifier]struct{}{},
		CredentialTypes: map[CredentialTypeIdentifier]struct{}{},
		PublicKeys:      map[IssuerIdentifier][]int{},
	}

	_ = dr.Disclose.Iterate(func(a *AttributeRequest) error {
		attr := a.Type
		ids.SchemeManagers[attr.CredentialTypeIdentifier().IssuerIdentifier().SchemeManagerIdentifier()] = struct{}{}
		ids.Issuers[attr.CredentialTypeIdentifier().IssuerIdentifier()] = struct{}{}
		ids.CredentialTypes[attr.CredentialTypeIdentifier()] = struct{}{}
		return nil
	})

	return ids
}

432
func (dr *DisclosureRequest) Identifiers() *IrmaIdentifierSet {
433
	if dr.ids == nil {
434
		dr.ids = dr.identifiers()
435
	}
436
	return dr.ids
437
438
439
440
441
442
443
444
445
}

func (dr *DisclosureRequest) Base() *BaseRequest {
	return &dr.BaseRequest
}

func (dr *DisclosureRequest) Action() Action { return ActionDisclosing }

func (dr *DisclosureRequest) Validate() error {
446
	if dr.LDContext != LDContextDisclosureRequest {
447
448
449
450
451
		return errors.New("Not a disclosure request")
	}
	if len(dr.Disclose) == 0 {
		return errors.New("Disclosure request had no attributes")
	}
452
	var err error
453
	for _, discon := range dr.Disclose {
454
455
		if err = discon.Validate(); err != nil {
			return err
456
457
		}
	}
458
459
	return nil
}
Sietse Ringers's avatar
Sietse Ringers committed
460

461
462
func (cr *CredentialRequest) Info(conf *Configuration, metadataVersion byte) (*CredentialInfo, error) {
	list, err := cr.AttributeList(conf, metadataVersion)
463
464
465
	if err != nil {
		return nil, err
	}
466
	return NewCredentialInfo(list.Ints, conf), nil
467
468
}

469
470
471
472
// Validate checks that this credential request is consistent with the specified Configuration:
// the credential type is known, all required attributes are present and no unknown attributes
// are given.
func (cr *CredentialRequest) Validate(conf *Configuration) error {
473
	credtype := conf.CredentialTypes[cr.CredentialTypeID]
Sietse Ringers's avatar
Sietse Ringers committed
474
	if credtype == nil {
475
		return errors.New("Credential request of unknown credential type")
Sietse Ringers's avatar
Sietse Ringers committed
476
	}
477
478
479
480
481

	// Check that there are no attributes in the credential request that aren't
	// in the credential descriptor.
	for crName := range cr.Attributes {
		found := false
482
		for _, ad := range credtype.AttributeTypes {
483
484
485
486
487
488
			if ad.ID == crName {
				found = true
				break
			}
		}
		if !found {
489
			return errors.New("Credential request contaiins unknown attribute")
490
		}
Sietse Ringers's avatar
Sietse Ringers committed
491
492
	}

493
	for _, attrtype := range credtype.AttributeTypes {
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
		if _, present := cr.Attributes[attrtype.ID]; !present && attrtype.Optional != "true" {
			return errors.New("Required attribute not present in credential request")
		}
	}

	return nil
}

// AttributeList returns the list of attributes from this credential request.
func (cr *CredentialRequest) AttributeList(conf *Configuration, metadataVersion byte) (*AttributeList, error) {
	if err := cr.Validate(conf); err != nil {
		return nil, err
	}

	// Compute metadata attribute
	meta := NewMetadataAttribute(metadataVersion)
	meta.setKeyCounter(cr.KeyCounter)
	meta.setCredentialTypeIdentifier(cr.CredentialTypeID.String())
	meta.setSigningDate()
	if err := meta.setExpiryDate(cr.Validity); err != nil {
		return nil, err
	}

	// Compute other attributes
518
	credtype := conf.CredentialTypes[cr.CredentialTypeID]
519
	attrs := make([]*big.Int, len(credtype.AttributeTypes)+1)
Sietse Ringers's avatar
Sietse Ringers committed
520
	attrs[0] = meta.Int
521
	for i, attrtype := range credtype.AttributeTypes {
522
		attrs[i+1] = new(big.Int)
Sietse Ringers's avatar
Sietse Ringers committed
523
		if str, present := cr.Attributes[attrtype.ID]; present {
524
			// Set attribute to str << 1 + 1
525
			attrs[i+1].SetBytes([]byte(str))
526
527
528
529
			if meta.Version() >= 0x03 {
				attrs[i+1].Lsh(attrs[i+1], 1)             // attr <<= 1
				attrs[i+1].Add(attrs[i+1], big.NewInt(1)) // attr += 1
			}
Sietse Ringers's avatar
Sietse Ringers committed
530
531
532
		}
	}

533
	return NewAttributeListFromInts(attrs, conf), nil
Sietse Ringers's avatar
Sietse Ringers committed
534
535
}

Sietse Ringers's avatar
Sietse Ringers committed
536
func (ir *IssuanceRequest) Identifiers() *IrmaIdentifierSet {
537
538
	if ir.ids == nil {
		ir.ids = &IrmaIdentifierSet{
539
540
541
542
			SchemeManagers:  map[SchemeManagerIdentifier]struct{}{},
			Issuers:         map[IssuerIdentifier]struct{}{},
			CredentialTypes: map[CredentialTypeIdentifier]struct{}{},
			PublicKeys:      map[IssuerIdentifier][]int{},
Sietse Ringers's avatar
Sietse Ringers committed
543
544
		}

Sietse Ringers's avatar
Sietse Ringers committed
545
		for _, credreq := range ir.Credentials {
Sietse Ringers's avatar
Sietse Ringers committed
546
			issuer := credreq.CredentialTypeID.IssuerIdentifier()
547
548
549
550
551
			ir.ids.SchemeManagers[issuer.SchemeManagerIdentifier()] = struct{}{}
			ir.ids.Issuers[issuer] = struct{}{}
			ir.ids.CredentialTypes[credreq.CredentialTypeID] = struct{}{}
			if ir.ids.PublicKeys[issuer] == nil {
				ir.ids.PublicKeys[issuer] = []int{}
552
			}
553
			ir.ids.PublicKeys[issuer] = append(ir.ids.PublicKeys[issuer], credreq.KeyCounter)
554
555
		}

556
		ir.ids.join(ir.DisclosureRequest.identifiers())
Sietse Ringers's avatar
Sietse Ringers committed
557
	}
558
	return ir.ids
Sietse Ringers's avatar
Sietse Ringers committed
559
560
}

Tomas's avatar
Tomas committed
561
562
563
564
565
566
567
568
569
570
571
572
573
func (ir *IssuanceRequest) GetCredentialInfoList(conf *Configuration, version *ProtocolVersion) (CredentialInfoList, error) {
	if ir.CredentialInfoList == nil {
		for _, credreq := range ir.Credentials {
			info, err := credreq.Info(conf, GetMetadataVersion(version))
			if err != nil {
				return nil, err
			}
			ir.CredentialInfoList = append(ir.CredentialInfoList, info)
		}
	}
	return ir.CredentialInfoList, nil
}

574
575
func (ir *IssuanceRequest) Action() Action { return ActionIssuing }

576
func (ir *IssuanceRequest) Validate() error {
577
	if ir.LDContext != LDContextIssuanceRequest {
578
579
580
581
582
		return errors.New("Not an issuance request")
	}
	if len(ir.Credentials) == 0 {
		return errors.New("Empty issuance request")
	}
583
	for _, cred := range ir.Credentials {
584
		if cred.Validity != nil && cred.Validity.Floor().Before(Timestamp(time.Now())) {
585
586
587
			return errors.New("Expired credential request")
		}
	}
588
589
590
591
592
593
	var err error
	for _, discon := range ir.Disclose {
		if err = discon.Validate(); err != nil {
			return err
		}
	}
594
595
596
	return nil
}

Sietse Ringers's avatar
Sietse Ringers committed
597
598
// GetNonce returns the nonce of this signature session
// (with the message already hashed into it).
599
600
func (sr *SignatureRequest) GetNonce(timestamp *atum.Timestamp) *big.Int {
	return ASN1ConvertSignatureNonce(sr.Message, sr.BaseRequest.GetNonce(nil), timestamp)
601
602
}

603
func (sr *SignatureRequest) SignatureFromMessage(message interface{}, timestamp *atum.Timestamp) (*SignedMessage, error) {
604
	signature, ok := message.(*Disclosure)
605
606
607
608
609

	if !ok {
		return nil, errors.Errorf("Type assertion failed")
	}

610
611
612
613
	nonce := sr.Nonce
	if nonce == nil {
		nonce = bigZero
	}
614
	return &SignedMessage{
615
		LDContext: LDContextSignedMessage,
616
		Signature: signature.Proofs,
617
		Indices:   signature.Indices,
618
619
		Nonce:     nonce,
		Context:   sr.GetContext(),
620
		Message:   sr.Message,
621
		Timestamp: timestamp,
622
623
624
	}, nil
}

625
626
func (sr *SignatureRequest) Action() Action { return ActionSigning }

627
func (sr *SignatureRequest) Validate() error {
628
	if sr.LDContext != LDContextSignatureRequest {
629
630
631
632
633
		return errors.New("Not a signature request")
	}
	if sr.Message == "" {
		return errors.New("Signature request had empty message")
	}
634
635
	if len(sr.Disclose) == 0 {
		return errors.New("Signature request had no attributes")
636
	}
637
	var err error
638
	for _, discon := range sr.Disclose {
639
640
		if err = discon.Validate(); err != nil {
			return err
641
642
		}
	}
643
644
645
	return nil
}

646
647
648
649
650
// Check if Timestamp is before other Timestamp. Used for checking expiry of attributes
func (t Timestamp) Before(u Timestamp) bool {
	return time.Time(t).Before(time.Time(u))
}

651
652
653
654
func (t Timestamp) After(u Timestamp) bool {
	return time.Time(t).After(time.Time(u))
}

655
656
// MarshalJSON marshals a timestamp.
func (t *Timestamp) MarshalJSON() ([]byte, error) {
657
	return []byte(t.String()), nil
658
659
660
661
662
663
664
665
666
667
668
}

// UnmarshalJSON unmarshals a timestamp.
func (t *Timestamp) UnmarshalJSON(b []byte) error {
	ts, err := strconv.Atoi(string(b))
	if err != nil {
		return err
	}
	*t = Timestamp(time.Unix(int64(ts), 0))
	return nil
}
Sietse Ringers's avatar
Sietse Ringers committed
669

670
671
672
673
674
// Timestamp implements Stringer.
func (t *Timestamp) String() string {
	return fmt.Sprint(time.Time(*t).Unix())
}

675
676
677
678
func (t *Timestamp) Floor() Timestamp {
	return Timestamp(time.Unix((time.Time(*t).Unix()/ExpiryFactor)*ExpiryFactor, 0))
}

679
680
681
682
683
684
685
686
func readTimestamp(path string) (*Timestamp, bool, error) {
	exists, err := fs.PathExists(path)
	if err != nil {
		return nil, false, err
	}
	if !exists {
		return nil, false, nil
	}
687
688
	bts, err := ioutil.ReadFile(path)
	if err != nil {
689
		return nil, true, errors.New("Could not read scheme manager timestamp")
690
	}
691
692
	ts, err := parseTimestamp(bts)
	return ts, true, err
693
694
}

695
func parseTimestamp(bts []byte) (*Timestamp, error) {
696
697
698
699
700
701
	// Remove final character \n if present
	if bts[len(bts)-1] == '\n' {
		bts = bts[:len(bts)-1]
	}
	// convert from byte slice to string; parse as int
	str, err := strconv.ParseInt(string(bts), 10, 64)
702
	if err != nil {
703
		return nil, err
704
	}
705
706
	ts := Timestamp(time.Unix(str, 0))
	return &ts, nil
707
708
}

Sietse Ringers's avatar
Sietse Ringers committed
709
710
711
712
713
714
715
716
// NewServiceProviderJwt returns a new ServiceProviderJwt.
func NewServiceProviderJwt(servername string, dr *DisclosureRequest) *ServiceProviderJwt {
	return &ServiceProviderJwt{
		ServerJwt: ServerJwt{
			ServerName: servername,
			IssuedAt:   Timestamp(time.Now()),
			Type:       "verification_request",
		},
717
718
719
720
		Request: &ServiceProviderRequest{
			RequestorBaseRequest: RequestorBaseRequest{ResultJwtValidity: 120},
			Request:              dr,
		},
Sietse Ringers's avatar
Sietse Ringers committed
721
722
723
724
725
726
727
728
729
730
731
	}
}

// NewSignatureRequestorJwt returns a new SignatureRequestorJwt.
func NewSignatureRequestorJwt(servername string, sr *SignatureRequest) *SignatureRequestorJwt {
	return &SignatureRequestorJwt{
		ServerJwt: ServerJwt{
			ServerName: servername,
			IssuedAt:   Timestamp(time.Now()),
			Type:       "signature_request",
		},
732
733
734
735
		Request: &SignatureRequestorRequest{
			RequestorBaseRequest: RequestorBaseRequest{ResultJwtValidity: 120},
			Request:              sr,
		},
Sietse Ringers's avatar
Sietse Ringers committed
736
737
738
739
740
741
742
743
744
745
746
	}
}

// NewIdentityProviderJwt returns a new IdentityProviderJwt.
func NewIdentityProviderJwt(servername string, ir *IssuanceRequest) *IdentityProviderJwt {
	return &IdentityProviderJwt{
		ServerJwt: ServerJwt{
			ServerName: servername,
			IssuedAt:   Timestamp(time.Now()),
			Type:       "issue_request",
		},
747
748
749
750
		Request: &IdentityProviderRequest{
			RequestorBaseRequest: RequestorBaseRequest{ResultJwtValidity: 120},
			Request:              ir,
		},
Sietse Ringers's avatar
Sietse Ringers committed
751
752
753
	}
}

754
755
756
757
758
759
760
func (jwt *ServerJwt) Requestor() string { return jwt.ServerName }

func (r *ServiceProviderRequest) Validate() error {
	if r.Request == nil {
		return errors.New("Not a ServiceProviderRequest")
	}
	return r.Request.Validate()
Sietse Ringers's avatar
Sietse Ringers committed
761
762
}

763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
func (r *SignatureRequestorRequest) Validate() error {
	if r.Request == nil {
		return errors.New("Not a SignatureRequestorRequest")
	}
	return r.Request.Validate()
}

func (r *IdentityProviderRequest) Validate() error {
	if r.Request == nil {
		return errors.New("Not a IdentityProviderRequest")
	}
	return r.Request.Validate()
}

func (r *ServiceProviderRequest) SessionRequest() SessionRequest {
	return r.Request
}

func (r *SignatureRequestorRequest) SessionRequest() SessionRequest {
	return r.Request
}

func (r *IdentityProviderRequest) SessionRequest() SessionRequest {
	return r.Request
}

func (r *ServiceProviderRequest) Base() RequestorBaseRequest {
	return r.RequestorBaseRequest
}

func (r *SignatureRequestorRequest) Base() RequestorBaseRequest {
	return r.RequestorBaseRequest
}

func (r *IdentityProviderRequest) Base() RequestorBaseRequest {
	return r.RequestorBaseRequest
}
800

801
// SessionRequest returns an IRMA session object.
802
func (claims *ServiceProviderJwt) SessionRequest() SessionRequest { return claims.Request.Request }
Sietse Ringers's avatar
Sietse Ringers committed
803

804
// SessionRequest returns an IRMA session object.
805
func (claims *SignatureRequestorJwt) SessionRequest() SessionRequest { return claims.Request.Request }
Sietse Ringers's avatar
Sietse Ringers committed
806

807
// SessionRequest returns an IRMA session object.
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
func (claims *IdentityProviderJwt) SessionRequest() SessionRequest { return claims.Request.Request }

func (claims *ServiceProviderJwt) Sign(method jwt.SigningMethod, key interface{}) (string, error) {
	return jwt.NewWithClaims(method, claims).SignedString(key)
}

func (claims *SignatureRequestorJwt) Sign(method jwt.SigningMethod, key interface{}) (string, error) {
	return jwt.NewWithClaims(method, claims).SignedString(key)
}

func (claims *IdentityProviderJwt) Sign(method jwt.SigningMethod, key interface{}) (string, error) {
	return jwt.NewWithClaims(method, claims).SignedString(key)
}

func (claims *ServiceProviderJwt) RequestorRequest() RequestorRequest { return claims.Request }

func (claims *SignatureRequestorJwt) RequestorRequest() RequestorRequest { return claims.Request }

func (claims *IdentityProviderJwt) RequestorRequest() RequestorRequest { return claims.Request }

func (claims *ServiceProviderJwt) Valid() error {
	if claims.Type != "verification_request" {
830
831
832

		return errors.New("Verification jwt has invalid subject")
	}
833
	if time.Time(claims.IssuedAt).After(time.Now()) {
834
835
836
837
838
		return errors.New("Verification jwt not yet valid")
	}
	return nil
}

839
840
func (claims *SignatureRequestorJwt) Valid() error {
	if claims.Type != "signature_request" {
841
842
		return errors.New("Signature jwt has invalid subject")
	}
843
	if time.Time(claims.IssuedAt).After(time.Now()) {
844
845
846
847
848
		return errors.New("Signature jwt not yet valid")
	}
	return nil
}

849
850
func (claims *IdentityProviderJwt) Valid() error {
	if claims.Type != "issue_request" {
851
852
		return errors.New("Issuance jwt has invalid subject")
	}
853
	if time.Time(claims.IssuedAt).After(time.Now()) {
854
855
856
857
858
		return errors.New("Issuance jwt not yet valid")
	}
	return nil
}

859
860
861
func (claims *ServiceProviderJwt) Action() Action { return ActionDisclosing }

func (claims *SignatureRequestorJwt) Action() Action { return ActionSigning }
862

863
func (claims *IdentityProviderJwt) Action() Action { return ActionIssuing }
864

865
func SignSessionRequest(request SessionRequest, alg jwt.SigningMethod, key interface{}, name string) (string, error) {
866
867
868
869
870
871
872
873
874
875
876
	var jwtcontents RequestorJwt
	switch r := request.(type) {
	case *IssuanceRequest:
		jwtcontents = NewIdentityProviderJwt(name, r)
	case *DisclosureRequest:
		jwtcontents = NewServiceProviderJwt(name, r)
	case *SignatureRequest:
		jwtcontents = NewSignatureRequestorJwt(name, r)
	}
	return jwtcontents.Sign(alg, key)
}
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892

func SignRequestorRequest(request RequestorRequest, alg jwt.SigningMethod, key interface{}, name string) (string, error) {
	var jwtcontents RequestorJwt
	switch r := request.(type) {
	case *IdentityProviderRequest:
		jwtcontents = NewIdentityProviderJwt(name, nil)
		jwtcontents.(*IdentityProviderJwt).Request = r
	case *ServiceProviderRequest:
		jwtcontents = NewServiceProviderJwt(name, nil)
		jwtcontents.(*ServiceProviderJwt).Request = r
	case *SignatureRequestorRequest:
		jwtcontents = NewSignatureRequestorJwt(name, nil)
		jwtcontents.(*SignatureRequestorJwt).Request = r
	}
	return jwtcontents.Sign(alg, key)
}
893
894
895
896
897

// NewAttributeRequest requests the specified attribute.
func NewAttributeRequest(attr string) AttributeRequest {
	return AttributeRequest{Type: NewAttributeTypeIdentifier(attr)}
}