requests.go 20 KB
Newer Older
1
package irma
2
3
4

import (
	"fmt"
5
	"io/ioutil"
6
7
8
	"strconv"
	"time"

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

16
17
// BaseRequest contains the context and nonce for an IRMA session.
type BaseRequest struct {
18
19
	Context *big.Int `json:"context,omitempty"`
	Nonce   *big.Int `json:"nonce,omitempty"`
20
	Type    Action   `json:"type"`
21

22
23
24
	Candidates [][]*AttributeIdentifier `json:"-"`
	Choice     *DisclosureChoice        `json:"-"`
	Ids        *IrmaIdentifierSet       `json:"-"`
25

26
	Version *ProtocolVersion `json:"protocolVersion,omitempty"`
Sietse Ringers's avatar
Sietse Ringers committed
27
28
}

29
func (sr *BaseRequest) SetCandidates(candidates [][]*AttributeIdentifier) {
30
31
32
	sr.Candidates = candidates
}

33
// DisclosureChoice returns the attributes to be disclosed in this session.
34
func (sr *BaseRequest) DisclosureChoice() *DisclosureChoice {
35
	return sr.Choice
Sietse Ringers's avatar
Sietse Ringers committed
36
37
}

38
// SetDisclosureChoice sets the attributes to be disclosed in this session.
39
func (sr *BaseRequest) SetDisclosureChoice(choice *DisclosureChoice) {
40
	sr.Choice = choice
41
42
}

43
// ...
44
func (sr *BaseRequest) SetVersion(v *ProtocolVersion) {
45
	sr.Version = v
46
47
48
}

// ...
49
func (sr *BaseRequest) GetVersion() *ProtocolVersion {
50
	return sr.Version
51
52
}

Sietse Ringers's avatar
Sietse Ringers committed
53
// A DisclosureRequest is a request to disclose certain attributes.
54
type DisclosureRequest struct {
55
	BaseRequest
56
57
58
	Content AttributeDisjunctionList `json:"content"`
}

Sietse Ringers's avatar
Sietse Ringers committed
59
// A SignatureRequest is a a request to sign a message with certain attributes.
60
61
type SignatureRequest struct {
	DisclosureRequest
62
63
64
	Message string `json:"message"`

	// Session state
65
	Timestamp *atum.Timestamp `json:"-"`
66
67
}

Sietse Ringers's avatar
Sietse Ringers committed
68
69
// An IssuanceRequest is a request to issue certain credentials,
// optionally also asking for certain attributes to be simultaneously disclosed.
70
type IssuanceRequest struct {
71
	BaseRequest
Tomas's avatar
Tomas committed
72
73
74
75
76
	Credentials []*CredentialRequest     `json:"credentials"`
	Disclose    AttributeDisjunctionList `json:"disclose"`

	// Derived data
	CredentialInfoList        CredentialInfoList `json:",omitempty"`
77
	RemovalCredentialInfoList CredentialInfoList `json:",omitempty"`
78
79
}

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

Sietse Ringers's avatar
Sietse Ringers committed
89
90
91
92
93
94
95
// ServerJwt contains standard JWT fields.
type ServerJwt struct {
	Type       string    `json:"sub"`
	ServerName string    `json:"iss"`
	IssuedAt   Timestamp `json:"iat"`
}

96
97
type RequestorBaseRequest struct {
	ResultJwtValidity int    `json:"validity"`    // Validity of session result JWT in seconds
98
	ClientTimeout     int    `json:"timeout"`     // Wait this many seconds for the IRMA app to connect before the session times out
99
100
101
102
103
104
	CallbackUrl       string `json:"callbackUrl"` // URL to post session result to
}

type RequestorRequest interface {
	Validator
	SessionRequest() SessionRequest
105
	Base() RequestorBaseRequest
106
107
}

Sietse Ringers's avatar
Sietse Ringers committed
108
109
// A ServiceProviderRequest contains a disclosure request.
type ServiceProviderRequest struct {
110
	RequestorBaseRequest
Sietse Ringers's avatar
Sietse Ringers committed
111
112
113
114
115
	Request *DisclosureRequest `json:"request"`
}

// A SignatureRequestorRequest contains a signing request.
type SignatureRequestorRequest struct {
116
	RequestorBaseRequest
Sietse Ringers's avatar
Sietse Ringers committed
117
118
119
120
121
	Request *SignatureRequest `json:"request"`
}

// An IdentityProviderRequest contains an issuance request.
type IdentityProviderRequest struct {
122
	RequestorBaseRequest
Sietse Ringers's avatar
Sietse Ringers committed
123
124
125
126
127
128
	Request *IssuanceRequest `json:"request"`
}

// ServiceProviderJwt is a requestor JWT for a disclosure session.
type ServiceProviderJwt struct {
	ServerJwt
129
	Request *ServiceProviderRequest `json:"sprequest"`
Sietse Ringers's avatar
Sietse Ringers committed
130
131
132
133
134
}

// SignatureRequestorJwt is a requestor JWT for a signing session.
type SignatureRequestorJwt struct {
	ServerJwt
135
	Request *SignatureRequestorRequest `json:"absrequest"`
Sietse Ringers's avatar
Sietse Ringers committed
136
137
138
139
140
}

// IdentityProviderJwt is a requestor JWT for issuance session.
type IdentityProviderJwt struct {
	ServerJwt
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
	Request *IdentityProviderRequest `json:"iprequest"`
}

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

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
Sietse Ringers's avatar
Sietse Ringers committed
175
176
}

177
178
179
180
181
182
183
184
185
186
187
188
func (r *ServiceProviderRequest) Base() RequestorBaseRequest {
	return r.RequestorBaseRequest
}

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

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

189
190
// SessionRequest is an IRMA session.
type SessionRequest interface {
191
	Validator
192
193
194
195
	GetNonce() *big.Int
	SetNonce(*big.Int)
	GetContext() *big.Int
	SetContext(*big.Int)
196
	GetVersion() *ProtocolVersion
197
	SetVersion(*ProtocolVersion)
198
	ToDisclose() AttributeDisjunctionList
199
200
	DisclosureChoice() *DisclosureChoice
	SetDisclosureChoice(choice *DisclosureChoice)
201
	SetCandidates(candidates [][]*AttributeIdentifier)
202
	Identifiers() *IrmaIdentifierSet
203
	Action() Action
204
205
}

Sietse Ringers's avatar
Sietse Ringers committed
206
207
208
// Timestamp is a time.Time that marshals to Unix timestamps.
type Timestamp time.Time

209
210
func (cr *CredentialRequest) Info(conf *Configuration, metadataVersion byte) (*CredentialInfo, error) {
	list, err := cr.AttributeList(conf, metadataVersion)
211
212
213
	if err != nil {
		return nil, err
	}
214
	return NewCredentialInfo(list.Ints, conf), nil
215
216
}

217
218
219
220
// 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 {
221
	credtype := conf.CredentialTypes[cr.CredentialTypeID]
Sietse Ringers's avatar
Sietse Ringers committed
222
	if credtype == nil {
223
		return errors.New("Credential request of unknown credential type")
Sietse Ringers's avatar
Sietse Ringers committed
224
	}
225
226
227
228
229

	// Check that there are no attributes in the credential request that aren't
	// in the credential descriptor.
	for crName := range cr.Attributes {
		found := false
230
		for _, ad := range credtype.AttributeTypes {
231
232
233
234
235
236
			if ad.ID == crName {
				found = true
				break
			}
		}
		if !found {
237
			return errors.New("Credential request contaiins unknown attribute")
238
		}
Sietse Ringers's avatar
Sietse Ringers committed
239
240
	}

241
	for _, attrtype := range credtype.AttributeTypes {
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
		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
266
	credtype := conf.CredentialTypes[cr.CredentialTypeID]
267
	attrs := make([]*big.Int, len(credtype.AttributeTypes)+1)
Sietse Ringers's avatar
Sietse Ringers committed
268
	attrs[0] = meta.Int
269
	for i, attrtype := range credtype.AttributeTypes {
270
		attrs[i+1] = new(big.Int)
Sietse Ringers's avatar
Sietse Ringers committed
271
		if str, present := cr.Attributes[attrtype.ID]; present {
272
			// Set attribute to str << 1 + 1
273
			attrs[i+1].SetBytes([]byte(str))
274
275
276
277
			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
278
279
280
		}
	}

281
	return NewAttributeListFromInts(attrs, conf), nil
Sietse Ringers's avatar
Sietse Ringers committed
282
283
}

Sietse Ringers's avatar
Sietse Ringers committed
284
func (ir *IssuanceRequest) Identifiers() *IrmaIdentifierSet {
285
286
	if ir.Ids == nil {
		ir.Ids = &IrmaIdentifierSet{
287
288
289
290
			SchemeManagers:  map[SchemeManagerIdentifier]struct{}{},
			Issuers:         map[IssuerIdentifier]struct{}{},
			CredentialTypes: map[CredentialTypeIdentifier]struct{}{},
			PublicKeys:      map[IssuerIdentifier][]int{},
Sietse Ringers's avatar
Sietse Ringers committed
291
292
		}

Sietse Ringers's avatar
Sietse Ringers committed
293
		for _, credreq := range ir.Credentials {
Sietse Ringers's avatar
Sietse Ringers committed
294
			issuer := credreq.CredentialTypeID.IssuerIdentifier()
295
296
			ir.Ids.SchemeManagers[issuer.SchemeManagerIdentifier()] = struct{}{}
			ir.Ids.Issuers[issuer] = struct{}{}
297
			ir.Ids.CredentialTypes[credreq.CredentialTypeID] = struct{}{}
298
299
			if ir.Ids.PublicKeys[issuer] == nil {
				ir.Ids.PublicKeys[issuer] = []int{}
300
			}
301
			ir.Ids.PublicKeys[issuer] = append(ir.Ids.PublicKeys[issuer], credreq.KeyCounter)
302
303
		}

Sietse Ringers's avatar
Sietse Ringers committed
304
		for _, disjunction := range ir.Disclose {
305
			for _, attr := range disjunction.Attributes {
Sietse Ringers's avatar
Sietse Ringers committed
306
307
308
309
310
311
				var cti CredentialTypeIdentifier
				if !attr.IsCredential() {
					cti = attr.CredentialTypeIdentifier()
				} else {
					cti = NewCredentialTypeIdentifier(attr.String())
				}
312
313
314
				ir.Ids.SchemeManagers[cti.IssuerIdentifier().SchemeManagerIdentifier()] = struct{}{}
				ir.Ids.Issuers[cti.IssuerIdentifier()] = struct{}{}
				ir.Ids.CredentialTypes[cti] = struct{}{}
315
			}
Sietse Ringers's avatar
Sietse Ringers committed
316
317
		}
	}
318
	return ir.Ids
Sietse Ringers's avatar
Sietse Ringers committed
319
320
}

Sietse Ringers's avatar
Sietse Ringers committed
321
// ToDisclose returns the attributes that must be disclosed in this issuance session.
322
323
324
325
326
327
328
func (ir *IssuanceRequest) ToDisclose() AttributeDisjunctionList {
	if ir.Disclose == nil {
		return AttributeDisjunctionList{}
	}

	return ir.Disclose
}
Sietse Ringers's avatar
Sietse Ringers committed
329

Tomas's avatar
Tomas committed
330
331
332
333
334
335
336
337
338
339
340
341
342
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
}

Sietse Ringers's avatar
Sietse Ringers committed
343
344
345
346
347
348
349
350
351
352
353
354
// GetContext returns the context of this session.
func (ir *IssuanceRequest) GetContext() *big.Int { return ir.Context }

// SetContext sets the context of this session.
func (ir *IssuanceRequest) SetContext(context *big.Int) { ir.Context = context }

// GetNonce returns the nonce of this session.
func (ir *IssuanceRequest) GetNonce() *big.Int { return ir.Nonce }

// SetNonce sets the nonce of this session.
func (ir *IssuanceRequest) SetNonce(nonce *big.Int) { ir.Nonce = nonce }

355
356
func (ir *IssuanceRequest) Action() Action { return ActionIssuing }

357
358
359
360
361
362
363
364
365
366
func (ir *IssuanceRequest) Validate() error {
	if ir.Type != ActionIssuing {
		return errors.New("Not an issuance request")
	}
	if len(ir.Credentials) == 0 {
		return errors.New("Empty issuance request")
	}
	return nil
}

367
func (dr *DisclosureRequest) Identifiers() *IrmaIdentifierSet {
368
369
	if dr.Ids == nil {
		dr.Ids = &IrmaIdentifierSet{
370
371
372
373
			SchemeManagers:  map[SchemeManagerIdentifier]struct{}{},
			Issuers:         map[IssuerIdentifier]struct{}{},
			CredentialTypes: map[CredentialTypeIdentifier]struct{}{},
			PublicKeys:      map[IssuerIdentifier][]int{},
Sietse Ringers's avatar
Sietse Ringers committed
374
		}
375
376
		for _, disjunction := range dr.Content {
			for _, attr := range disjunction.Attributes {
377
378
379
				dr.Ids.SchemeManagers[attr.CredentialTypeIdentifier().IssuerIdentifier().SchemeManagerIdentifier()] = struct{}{}
				dr.Ids.Issuers[attr.CredentialTypeIdentifier().IssuerIdentifier()] = struct{}{}
				dr.Ids.CredentialTypes[attr.CredentialTypeIdentifier()] = struct{}{}
380
			}
Sietse Ringers's avatar
Sietse Ringers committed
381
382
		}
	}
383
	return dr.Ids
Sietse Ringers's avatar
Sietse Ringers committed
384
385
}

Sietse Ringers's avatar
Sietse Ringers committed
386
387
// ToDisclose returns the attributes to be disclosed in this session.
func (dr *DisclosureRequest) ToDisclose() AttributeDisjunctionList { return dr.Content }
Sietse Ringers's avatar
Sietse Ringers committed
388
389
390
391
392
393
394
395
396
397
398
399
400

// GetContext returns the context of this session.
func (dr *DisclosureRequest) GetContext() *big.Int { return dr.Context }

// SetContext sets the context of this session.
func (dr *DisclosureRequest) SetContext(context *big.Int) { dr.Context = context }

// GetNonce returns the nonce of this session.
func (dr *DisclosureRequest) GetNonce() *big.Int { return dr.Nonce }

// SetNonce sets the nonce of this session.
func (dr *DisclosureRequest) SetNonce(nonce *big.Int) { dr.Nonce = nonce }

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

403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
func (dr *DisclosureRequest) Validate() error {
	if dr.Type != ActionDisclosing {
		return errors.New("Not a disclosure request")
	}
	if len(dr.Content) == 0 {
		return errors.New("Disclosure request had no attributes")
	}
	for _, disjunction := range dr.Content {
		if len(disjunction.Attributes) == 0 {
			return errors.New("Disclosure request had an empty disjunction")
		}
	}
	return nil
}

Sietse Ringers's avatar
Sietse Ringers committed
418
419
// GetNonce returns the nonce of this signature session
// (with the message already hashed into it).
420
func (sr *SignatureRequest) GetNonce() *big.Int {
421
	return ASN1ConvertSignatureNonce(sr.Message, sr.Nonce, sr.Timestamp)
422
423
}

424
func (sr *SignatureRequest) SignatureFromMessage(message interface{}) (*SignedMessage, error) {
425
	signature, ok := message.(*Disclosure)
426
427
428
429
430

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

431
	return &SignedMessage{
432
		Signature: signature.Proofs,
433
		Indices:   signature.Indices,
434
435
436
		Nonce:     sr.Nonce,
		Context:   sr.Context,
		Message:   sr.Message,
437
		Timestamp: sr.Timestamp,
438
439
440
	}, nil
}

441
442
func (sr *SignatureRequest) Action() Action { return ActionSigning }

443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
func (sr *SignatureRequest) Validate() error {
	if sr.Type != ActionSigning {
		return errors.New("Not a signature request")
	}
	if sr.Message == "" {
		return errors.New("Signature request had empty message")
	}
	if len(sr.Content) == 0 {
		return errors.New("Disclosure request had no attributes")
	}
	for _, disjunction := range sr.Content {
		if len(disjunction.Attributes) == 0 {
			return errors.New("Disclosure request had an empty disjunction")
		}
	}
	return nil
}

461
462
463
464
465
// 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))
}

466
467
468
469
func (t Timestamp) After(u Timestamp) bool {
	return time.Time(t).After(time.Time(u))
}

470
471
// MarshalJSON marshals a timestamp.
func (t *Timestamp) MarshalJSON() ([]byte, error) {
472
	return []byte(t.String()), nil
473
474
475
476
477
478
479
480
481
482
483
}

// 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
484

485
486
487
488
489
// Timestamp implements Stringer.
func (t *Timestamp) String() string {
	return fmt.Sprint(time.Time(*t).Unix())
}

490
491
492
493
494
495
496
497
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
	}
498
499
	bts, err := ioutil.ReadFile(path)
	if err != nil {
500
		return nil, true, errors.New("Could not read scheme manager timestamp")
501
	}
502
503
	ts, err := parseTimestamp(bts)
	return ts, true, err
504
505
}

506
func parseTimestamp(bts []byte) (*Timestamp, error) {
507
508
509
510
511
512
	// 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)
513
	if err != nil {
514
		return nil, err
515
	}
516
517
	ts := Timestamp(time.Unix(str, 0))
	return &ts, nil
518
519
}

Sietse Ringers's avatar
Sietse Ringers committed
520
521
522
523
524
525
526
527
// 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",
		},
528
529
530
531
		Request: &ServiceProviderRequest{
			RequestorBaseRequest: RequestorBaseRequest{ResultJwtValidity: 120},
			Request:              dr,
		},
Sietse Ringers's avatar
Sietse Ringers committed
532
533
534
535
536
537
538
539
540
541
542
	}
}

// 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",
		},
543
544
545
546
		Request: &SignatureRequestorRequest{
			RequestorBaseRequest: RequestorBaseRequest{ResultJwtValidity: 120},
			Request:              sr,
		},
Sietse Ringers's avatar
Sietse Ringers committed
547
548
549
550
551
552
553
554
555
556
557
	}
}

// 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",
		},
558
559
560
561
		Request: &IdentityProviderRequest{
			RequestorBaseRequest: RequestorBaseRequest{ResultJwtValidity: 120},
			Request:              ir,
		},
Sietse Ringers's avatar
Sietse Ringers committed
562
563
564
565
566
	}
}

// A RequestorJwt contains an IRMA session object.
type RequestorJwt interface {
567
	Action() Action
568
	RequestorRequest() RequestorRequest
569
	SessionRequest() SessionRequest
570
	Requestor() string
571
	Valid() error
572
	Sign(jwt.SigningMethod, interface{}) (string, error)
Sietse Ringers's avatar
Sietse Ringers committed
573
574
}

575
576
func (jwt *ServerJwt) Requestor() string { return jwt.ServerName }

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

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

583
// SessionRequest returns an IRMA session object.
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
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" {
606
607
608

		return errors.New("Verification jwt has invalid subject")
	}
609
	if time.Time(claims.IssuedAt).After(time.Now()) {
610
611
612
613
614
		return errors.New("Verification jwt not yet valid")
	}
	return nil
}

615
616
func (claims *SignatureRequestorJwt) Valid() error {
	if claims.Type != "signature_request" {
617
618
		return errors.New("Signature jwt has invalid subject")
	}
619
	if time.Time(claims.IssuedAt).After(time.Now()) {
620
621
622
623
624
		return errors.New("Signature jwt not yet valid")
	}
	return nil
}

625
626
func (claims *IdentityProviderJwt) Valid() error {
	if claims.Type != "issue_request" {
627
628
		return errors.New("Issuance jwt has invalid subject")
	}
629
	if time.Time(claims.IssuedAt).After(time.Now()) {
630
631
632
633
634
		return errors.New("Issuance jwt not yet valid")
	}
	return nil
}

635
636
637
func (claims *ServiceProviderJwt) Action() Action { return ActionDisclosing }

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

639
func (claims *IdentityProviderJwt) Action() Action { return ActionIssuing }
640

641
func SignSessionRequest(request SessionRequest, alg jwt.SigningMethod, key interface{}, name string) (string, error) {
642
643
644
645
646
647
648
649
650
651
652
	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)
}
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668

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)
}