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

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

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

19 20 21 22 23 24
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"
)

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

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

34 35 36 37
	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
38 39

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

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

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

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

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

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

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

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

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

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

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

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

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

109 110
// RequestorBaseRequest contains fields present in all RequestorRequest types
// with which the requestor configures an IRMA session.
111
type RequestorBaseRequest struct {
Sietse Ringers's avatar
Sietse Ringers committed
112 113
	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
114
	CallbackURL       string `json:"callbackUrl,omitempty"` // URL to post session result to
115 116
}

117 118
// 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.
119 120 121
type RequestorRequest interface {
	Validator
	SessionRequest() SessionRequest
122
	Base() RequestorBaseRequest
123 124
}

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

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

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

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

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

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

161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
// 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 {
179 180 181
	Type    AttributeTypeIdentifier `json:"type"`
	Value   *string                 `json:"value,omitempty"`
	NotNull bool                    `json:"notNull,omitempty"`
182 183 184 185 186 187 188
}

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

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

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

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

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

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

218
	return result
219 220
}

221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
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
}

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

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

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

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

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

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

268 269
// 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.
270
func (c AttributeCon) Satisfy(proofs gabi.ProofList, indices []*DisclosedAttributeIndex, conf *Configuration) (bool, []*DisclosedAttribute, error) {
271
	if len(indices) < len(c) {
272
		return false, nil, nil
273 274
	}
	attrs := make([]*DisclosedAttribute, 0, len(c))
275 276 277
	if len(c) == 0 {
		return true, attrs, nil
	}
278 279 280 281 282

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

293 294 295 296 297 298 299 300 301 302 303 304 305
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
}

306 307
// 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.
308
func (dc AttributeDisCon) Satisfy(proofs gabi.ProofList, indices []*DisclosedAttributeIndex, conf *Configuration) (bool, []*DisclosedAttribute, error) {
309
	for _, con := range dc {
310 311 312
		satisfied, attrs, err := con.Satisfy(proofs, indices, conf)
		if satisfied || err != nil {
			return true, attrs, err
313 314
		}
	}
315
	return false, nil, nil
316 317
}

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

337 338
// Satisfy returns true if each of the contained AttributeDisCon is satisfied by the specified disclosure.
// If so it also returns the disclosed attributes.
339 340 341 342 343 344 345 346
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 {
347
		satisfied, attrs, err := discon.Satisfy(disclosure.Proofs, disclosure.Indices[i], conf)
348 349 350
		if err != nil {
			return false, nil, err
		}
351
		if satisfied {
352 353 354 355 356 357 358 359
			list[i] = attrs
		} else {
			complete = false
			list[i] = nil
		}
	}

	return complete, list, nil
360 361
}

362 363 364 365 366 367 368 369 370 371 372 373
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
374 375
}

376 377 378 379 380 381 382
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{
383
		BaseRequest: BaseRequest{LDContext: LDContextDisclosureRequest},
384 385 386 387 388 389 390 391 392 393
		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...)
394
	dr.LDContext = LDContextSignatureRequest
395
	return &SignatureRequest{
396
		DisclosureRequest: *dr,
397 398 399 400 401 402
		Message:           message,
	}
}

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

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

414 415 416 417 418 419
func (dr *DisclosureRequest) identifiers() *IrmaIdentifierSet {
	ids := &IrmaIdentifierSet{
		SchemeManagers:  map[SchemeManagerIdentifier]struct{}{},
		Issuers:         map[IssuerIdentifier]struct{}{},
		CredentialTypes: map[CredentialTypeIdentifier]struct{}{},
		PublicKeys:      map[IssuerIdentifier][]int{},
Leon's avatar
Leon committed
420
		AttributeTypes:  map[AttributeTypeIdentifier]struct{}{},
421 422 423 424 425 426 427
	}

	_ = 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{}{}
Leon's avatar
Leon committed
428
		ids.AttributeTypes[attr] = struct{}{}
429 430 431 432 433 434
		return nil
	})

	return ids
}

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

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

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

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

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

472 473 474 475
// 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 {
476
	credtype := conf.CredentialTypes[cr.CredentialTypeID]
Sietse Ringers's avatar
Sietse Ringers committed
477
	if credtype == nil {
478
		return errors.New("Credential request of unknown credential type")
Sietse Ringers's avatar
Sietse Ringers committed
479
	}
480 481 482 483 484

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

496
	for _, attrtype := range credtype.AttributeTypes {
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
		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
521
	credtype := conf.CredentialTypes[cr.CredentialTypeID]
522
	attrs := make([]*big.Int, len(credtype.AttributeTypes)+1)
Sietse Ringers's avatar
Sietse Ringers committed
523
	attrs[0] = meta.Int
524
	for i, attrtype := range credtype.AttributeTypes {
525
		attrs[i+1] = new(big.Int)
Sietse Ringers's avatar
Sietse Ringers committed
526
		if str, present := cr.Attributes[attrtype.ID]; present {
527
			// Set attribute to str << 1 + 1
528
			attrs[i+1].SetBytes([]byte(str))
529 530 531 532
			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
533 534 535
		}
	}

536
	return NewAttributeListFromInts(attrs, conf), nil
Sietse Ringers's avatar
Sietse Ringers committed
537 538
}

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

Sietse Ringers's avatar
Sietse Ringers committed
549
		for _, credreq := range ir.Credentials {
Sietse Ringers's avatar
Sietse Ringers committed
550
			issuer := credreq.CredentialTypeID.IssuerIdentifier()
551 552
			ir.ids.SchemeManagers[issuer.SchemeManagerIdentifier()] = struct{}{}
			ir.ids.Issuers[issuer] = struct{}{}
Leon's avatar
Leon committed
553 554 555 556 557
			credID := credreq.CredentialTypeID
			ir.ids.CredentialTypes[credID] = struct{}{}
			for attr, _ := range credreq.Attributes { // this is kind of ugly
				ir.ids.AttributeTypes[NewAttributeTypeIdentifier(credID.String()+"."+attr)] = struct{}{}
			}
558 559
			if ir.ids.PublicKeys[issuer] == nil {
				ir.ids.PublicKeys[issuer] = []int{}
560
			}
561
			ir.ids.PublicKeys[issuer] = append(ir.ids.PublicKeys[issuer], credreq.KeyCounter)
562 563
		}

564
		ir.ids.join(ir.DisclosureRequest.identifiers())
Sietse Ringers's avatar
Sietse Ringers committed
565
	}
566
	return ir.ids
Sietse Ringers's avatar
Sietse Ringers committed
567 568
}

Tomas's avatar
Tomas committed
569 570 571 572 573 574 575 576 577 578 579 580 581
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
}

582 583
func (ir *IssuanceRequest) Action() Action { return ActionIssuing }

584
func (ir *IssuanceRequest) Validate() error {
585
	if ir.LDContext != LDContextIssuanceRequest {
586 587 588 589 590
		return errors.New("Not an issuance request")
	}
	if len(ir.Credentials) == 0 {
		return errors.New("Empty issuance request")
	}
591
	for _, cred := range ir.Credentials {
592
		if cred.Validity != nil && cred.Validity.Floor().Before(Timestamp(time.Now())) {
593 594 595
			return errors.New("Expired credential request")
		}
	}
596 597 598 599 600 601
	var err error
	for _, discon := range ir.Disclose {
		if err = discon.Validate(); err != nil {
			return err
		}
	}
602 603 604
	return nil
}

Sietse Ringers's avatar
Sietse Ringers committed
605 606
// GetNonce returns the nonce of this signature session
// (with the message already hashed into it).
607 608
func (sr *SignatureRequest) GetNonce(timestamp *atum.Timestamp) *big.Int {
	return ASN1ConvertSignatureNonce(sr.Message, sr.BaseRequest.GetNonce(nil), timestamp)
609 610
}

611
func (sr *SignatureRequest) SignatureFromMessage(message interface{}, timestamp *atum.Timestamp) (*SignedMessage, error) {
612
	signature, ok := message.(*Disclosure)
613 614 615 616 617

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

618 619 620 621
	nonce := sr.Nonce
	if nonce == nil {
		nonce = bigZero
	}
622
	return &SignedMessage{
623
		LDContext: LDContextSignedMessage,
624
		Signature: signature.Proofs,
625
		Indices:   signature.Indices,
626 627
		Nonce:     nonce,
		Context:   sr.GetContext(),
628
		Message:   sr.Message,
629
		Timestamp: timestamp,
630 631 632
	}, nil
}

633 634
func (sr *SignatureRequest) Action() Action { return ActionSigning }

635
func (sr *SignatureRequest) Validate() error {
636
	if sr.LDContext != LDContextSignatureRequest {
637 638 639 640 641
		return errors.New("Not a signature request")
	}
	if sr.Message == "" {
		return errors.New("Signature request had empty message")
	}
642 643
	if len(sr.Disclose) == 0 {
		return errors.New("Signature request had no attributes")
644
	}
645
	var err error
646
	for _, discon := range sr.Disclose {
647 648
		if err = discon.Validate(); err != nil {
			return err
649 650
		}
	}
651 652 653
	return nil
}

654 655 656 657 658
// 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))
}

659 660 661 662
func (t Timestamp) After(u Timestamp) bool {
	return time.Time(t).After(time.Time(u))
}

663 664 665 666 667
// To check whether Timestamp is uninitialized
func (t Timestamp) IsZero() bool {
	return time.Time(t).IsZero()
}

668 669 670 671 672 673 674 675 676 677 678 679 680
func (t *Timestamp) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	return e.EncodeElement(t.String(), start)
}

func (t *Timestamp) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	var ts int64
	if err := d.DecodeElement(&ts, &start); err != nil {
		return err
	}
	*t = Timestamp(time.Unix(ts, 0))
	return nil
}

681 682
// MarshalJSON marshals a timestamp.
func (t *Timestamp) MarshalJSON() ([]byte, error) {
683
	return []byte(t.String()), nil
684 685 686 687 688 689 690 691 692 693 694
}

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

696 697 698 699 700
// Timestamp implements Stringer.
func (t *Timestamp) String() string {
	return fmt.Sprint(time.Time(*t).Unix())
}

701 702 703 704
func (t *Timestamp) Floor() Timestamp {
	return Timestamp(time.Unix((time.Time(*t).Unix()/ExpiryFactor)*ExpiryFactor, 0))
}

705 706 707 708 709 710 711 712
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
	}
713 714
	bts, err := ioutil.ReadFile(path)
	if err != nil {
715
		return nil, true, errors.New("Could not read scheme manager timestamp")
716
	}
717 718
	ts, err := parseTimestamp(bts)
	return ts, true, err
719 720
}

721
func parseTimestamp(bts []byte) (*Timestamp, error) {
722 723 724 725 726 727
	// 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)
728
	if err != nil {
729
		return nil, err
730
	}
731 732
	ts := Timestamp(time.Unix(str, 0))
	return &ts, nil
733 734
}

Sietse Ringers's avatar
Sietse Ringers committed
735 736 737 738 739 740 741 742
// 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",
		},
743 744 745 746
		Request: &ServiceProviderRequest{
			RequestorBaseRequest: RequestorBaseRequest{ResultJwtValidity: 120},
			Request:              dr,
		},
Sietse Ringers's avatar
Sietse Ringers committed
747 748 749 750 751 752 753 754 755 756 757
	}
}

// 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",
		},
758 759 760 761
		Request: &SignatureRequestorRequest{
			RequestorBaseRequest: RequestorBaseRequest{ResultJwtValidity: 120},
			Request:              sr,
		},
Sietse Ringers's avatar
Sietse Ringers committed
762 763 764 765 766 767 768 769 770 771 772
	}
}

// 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",
		},
773 774 775 776
		Request: &IdentityProviderRequest{
			RequestorBaseRequest: RequestorBaseRequest{ResultJwtValidity: 120},
			Request:              ir,
		},
Sietse Ringers's avatar
Sietse Ringers committed
777 778 779
	}
}

780 781 782 783 784 785 786
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
787 788
}

789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825
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
}
826

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

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

833
// SessionRequest returns an IRMA session object.
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855
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" {
856 857 858

		return errors.New("Verification jwt has invalid subject")
	}
859
	if time.Time(claims.IssuedAt).After(time.Now()) {
860 861 862 863 864
		return errors.New("Verification jwt not yet valid")
	}
	return nil
}

865 866
func (claims *SignatureRequestorJwt) Valid() error {
	if claims.Type != "signature_request" {
867 868
		return errors.New("Signature jwt has invalid subject")
	}
869
	if time.Time(claims.IssuedAt).After(time.Now()) {
870 871 872 873 874
		return errors.New("Signature jwt not yet valid")
	}
	return nil
}

875 876
func (claims *IdentityProviderJwt) Valid() error {
	if claims.Type != "issue_request" {
877 878
		return errors.New("Issuance jwt has invalid subject")
	}
879
	if time.Time(claims.IssuedAt).After(time.Now()) {
880 881 882 883 884
		return errors.New("Issuance jwt not yet valid")
	}
	return nil
}

885 886 887
func (claims *ServiceProviderJwt) Action() Action { return ActionDisclosing }

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

889
func (claims *IdentityProviderJwt) Action() Action { return ActionIssuing }
890

891
func SignSessionRequest(request SessionRequest, alg jwt.SigningMethod, key interface{}, name string) (string, error) {
892 893 894 895 896 897 898 899 900 901 902
	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)
}
903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918

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)
}
919 920 921 922 923

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