github.com/freetocompute/snapd@v0.0.0-20210618182524-2fb355d72fd9/asserts/asserts.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2015-2020 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package asserts 21 22 import ( 23 "bufio" 24 "bytes" 25 "crypto" 26 "fmt" 27 "io" 28 "sort" 29 "strconv" 30 "strings" 31 "unicode/utf8" 32 ) 33 34 type typeFlags int 35 36 const ( 37 noAuthority typeFlags = 1 << iota 38 sequenceForming 39 ) 40 41 // MetaHeaders is a list of headers in assertions which are about the assertion 42 // itself. 43 var MetaHeaders = [...]string{ 44 "type", 45 "format", 46 "authority-id", 47 "revision", 48 "body-length", 49 "sign-key-sha3-384", 50 } 51 52 // AssertionType describes a known assertion type with its name and metadata. 53 type AssertionType struct { 54 // Name of the type. 55 Name string 56 // PrimaryKey holds the names of the headers that constitute the 57 // unique primary key for this assertion type. 58 PrimaryKey []string 59 60 assembler func(assert assertionBase) (Assertion, error) 61 flags typeFlags 62 } 63 64 // MaxSupportedFormat returns the maximum supported format iteration for the type. 65 func (at *AssertionType) MaxSupportedFormat() int { 66 return maxSupportedFormat[at.Name] 67 } 68 69 // SequencingForming returns true if the assertion type has a positive 70 // integer >= 1 as the last component (preferably called "sequence") 71 // of its primary key over which the assertions of the type form 72 // sequences, usually without gaps, one sequence per sequence key (the 73 // primary key prefix omitting the sequence number). 74 // See SequenceMember. 75 func (at *AssertionType) SequenceForming() bool { 76 return at.flags&sequenceForming != 0 77 } 78 79 // Understood assertion types. 80 var ( 81 AccountType = &AssertionType{"account", []string{"account-id"}, assembleAccount, 0} 82 AccountKeyType = &AssertionType{"account-key", []string{"public-key-sha3-384"}, assembleAccountKey, 0} 83 RepairType = &AssertionType{"repair", []string{"brand-id", "repair-id"}, assembleRepair, sequenceForming} 84 ModelType = &AssertionType{"model", []string{"series", "brand-id", "model"}, assembleModel, 0} 85 SerialType = &AssertionType{"serial", []string{"brand-id", "model", "serial"}, assembleSerial, 0} 86 BaseDeclarationType = &AssertionType{"base-declaration", []string{"series"}, assembleBaseDeclaration, 0} 87 SnapDeclarationType = &AssertionType{"snap-declaration", []string{"series", "snap-id"}, assembleSnapDeclaration, 0} 88 SnapBuildType = &AssertionType{"snap-build", []string{"snap-sha3-384"}, assembleSnapBuild, 0} 89 SnapRevisionType = &AssertionType{"snap-revision", []string{"snap-sha3-384"}, assembleSnapRevision, 0} 90 SnapDeveloperType = &AssertionType{"snap-developer", []string{"snap-id", "publisher-id"}, assembleSnapDeveloper, 0} 91 SystemUserType = &AssertionType{"system-user", []string{"brand-id", "email"}, assembleSystemUser, 0} 92 ValidationType = &AssertionType{"validation", []string{"series", "snap-id", "approved-snap-id", "approved-snap-revision"}, assembleValidation, 0} 93 ValidationSetType = &AssertionType{"validation-set", []string{"series", "account-id", "name", "sequence"}, assembleValidationSet, sequenceForming} 94 StoreType = &AssertionType{"store", []string{"store"}, assembleStore, 0} 95 96 // ... 97 ) 98 99 // Assertion types without a definite authority set (on the wire and/or self-signed). 100 var ( 101 DeviceSessionRequestType = &AssertionType{"device-session-request", []string{"brand-id", "model", "serial"}, assembleDeviceSessionRequest, noAuthority} 102 SerialRequestType = &AssertionType{"serial-request", nil, assembleSerialRequest, noAuthority} 103 AccountKeyRequestType = &AssertionType{"account-key-request", []string{"public-key-sha3-384"}, assembleAccountKeyRequest, noAuthority} 104 ) 105 106 var typeRegistry = map[string]*AssertionType{ 107 AccountType.Name: AccountType, 108 AccountKeyType.Name: AccountKeyType, 109 ModelType.Name: ModelType, 110 SerialType.Name: SerialType, 111 BaseDeclarationType.Name: BaseDeclarationType, 112 SnapDeclarationType.Name: SnapDeclarationType, 113 SnapBuildType.Name: SnapBuildType, 114 SnapRevisionType.Name: SnapRevisionType, 115 SnapDeveloperType.Name: SnapDeveloperType, 116 SystemUserType.Name: SystemUserType, 117 ValidationType.Name: ValidationType, 118 ValidationSetType.Name: ValidationSetType, 119 RepairType.Name: RepairType, 120 StoreType.Name: StoreType, 121 // no authority 122 DeviceSessionRequestType.Name: DeviceSessionRequestType, 123 SerialRequestType.Name: SerialRequestType, 124 AccountKeyRequestType.Name: AccountKeyRequestType, 125 } 126 127 // Type returns the AssertionType with name or nil 128 func Type(name string) *AssertionType { 129 return typeRegistry[name] 130 } 131 132 // TypeNames returns a sorted list of known assertion type names. 133 func TypeNames() []string { 134 names := make([]string, 0, len(typeRegistry)) 135 for k := range typeRegistry { 136 names = append(names, k) 137 } 138 139 sort.Strings(names) 140 141 return names 142 } 143 144 var maxSupportedFormat = map[string]int{} 145 146 func init() { 147 // register maxSupportedFormats while breaking initialisation loop 148 149 // 1: plugs and slots 150 // 2: support for $SLOT()/$PLUG()/$MISSING 151 // 3: support for on-store/on-brand/on-model device scope constraints 152 // 4: support for plug-names/slot-names constraints 153 maxSupportedFormat[SnapDeclarationType.Name] = 4 154 155 // 1: support to limit to device serials 156 maxSupportedFormat[SystemUserType.Name] = 1 157 } 158 159 func MockMaxSupportedFormat(assertType *AssertionType, maxFormat int) (restore func()) { 160 prev := maxSupportedFormat[assertType.Name] 161 maxSupportedFormat[assertType.Name] = maxFormat 162 return func() { 163 maxSupportedFormat[assertType.Name] = prev 164 } 165 } 166 167 var formatAnalyzer = map[*AssertionType]func(headers map[string]interface{}, body []byte) (formatnum int, err error){ 168 SnapDeclarationType: snapDeclarationFormatAnalyze, 169 SystemUserType: systemUserFormatAnalyze, 170 } 171 172 // MaxSupportedFormats returns a mapping between assertion type names 173 // and corresponding max supported format if it is >= min. Typical 174 // usage passes 1 or 0 for min. 175 func MaxSupportedFormats(min int) (maxFormats map[string]int) { 176 if min == 0 { 177 maxFormats = make(map[string]int, len(typeRegistry)) 178 } else { 179 maxFormats = make(map[string]int) 180 } 181 for name := range typeRegistry { 182 m := maxSupportedFormat[name] 183 if m >= min { 184 maxFormats[name] = m 185 } 186 } 187 return maxFormats 188 } 189 190 // SuggestFormat returns a minimum format that supports the features that would be used by an assertion with the given components. 191 func SuggestFormat(assertType *AssertionType, headers map[string]interface{}, body []byte) (formatnum int, err error) { 192 analyzer := formatAnalyzer[assertType] 193 if analyzer == nil { 194 // no analyzer, format 0 is all there is 195 return 0, nil 196 } 197 formatnum, err = analyzer(headers, body) 198 if err != nil { 199 return 0, fmt.Errorf("assertion %s: %v", assertType.Name, err) 200 } 201 return formatnum, nil 202 } 203 204 // HeadersFromPrimaryKey constructs a headers mapping from the 205 // primaryKey values and the assertion type, it errors if primaryKey 206 // has the wrong length. 207 func HeadersFromPrimaryKey(assertType *AssertionType, primaryKey []string) (headers map[string]string, err error) { 208 if len(primaryKey) != len(assertType.PrimaryKey) { 209 return nil, fmt.Errorf("primary key has wrong length for %q assertion", assertType.Name) 210 } 211 headers = make(map[string]string, len(assertType.PrimaryKey)) 212 for i, name := range assertType.PrimaryKey { 213 keyVal := primaryKey[i] 214 if keyVal == "" { 215 return nil, fmt.Errorf("primary key %q header cannot be empty", name) 216 } 217 headers[name] = keyVal 218 } 219 return headers, nil 220 } 221 222 // HeadersFromSequenceKey constructs a headers mapping from the 223 // sequenceKey values and the sequence forming assertion type, 224 // it errors if sequenceKey has the wrong length; the length must be 225 // one less than the primary key of the given assertion type. 226 func HeadersFromSequenceKey(assertType *AssertionType, sequenceKey []string) (headers map[string]string, err error) { 227 if !assertType.SequenceForming() { 228 return nil, fmt.Errorf("internal error: HeadersFromSequenceKey should only be used for sequence forming assertion types, got: %s", assertType.Name) 229 } 230 if len(sequenceKey) != len(assertType.PrimaryKey)-1 { 231 return nil, fmt.Errorf("sequence key has wrong length for %q assertion", assertType.Name) 232 } 233 headers = make(map[string]string, len(sequenceKey)) 234 for i, val := range sequenceKey { 235 key := assertType.PrimaryKey[i] 236 if val == "" { 237 return nil, fmt.Errorf("sequence key %q header cannot be empty", key) 238 } 239 headers[key] = val 240 } 241 return headers, nil 242 } 243 244 // PrimaryKeyFromHeaders extracts the tuple of values from headers 245 // corresponding to a primary key under the assertion type, it errors 246 // if there are missing primary key headers. 247 func PrimaryKeyFromHeaders(assertType *AssertionType, headers map[string]string) (primaryKey []string, err error) { 248 return keysFromHeaders(assertType.PrimaryKey, headers) 249 } 250 251 func keysFromHeaders(keys []string, headers map[string]string) (keyValues []string, err error) { 252 keyValues = make([]string, len(keys)) 253 for i, k := range keys { 254 keyVal := headers[k] 255 if keyVal == "" { 256 return nil, fmt.Errorf("must provide primary key: %v", k) 257 } 258 keyValues[i] = keyVal 259 } 260 return keyValues, nil 261 } 262 263 // Ref expresses a reference to an assertion. 264 type Ref struct { 265 Type *AssertionType 266 PrimaryKey []string 267 } 268 269 func (ref *Ref) String() string { 270 pkStr := "-" 271 n := len(ref.Type.PrimaryKey) 272 if n != len(ref.PrimaryKey) { 273 pkStr = "???" 274 } else if n > 0 { 275 pkStr = ref.PrimaryKey[n-1] 276 if n > 1 { 277 sfx := []string{pkStr + ";"} 278 for i, k := range ref.Type.PrimaryKey[:n-1] { 279 sfx = append(sfx, fmt.Sprintf("%s:%s", k, ref.PrimaryKey[i])) 280 } 281 pkStr = strings.Join(sfx, " ") 282 } 283 } 284 return fmt.Sprintf("%s (%s)", ref.Type.Name, pkStr) 285 } 286 287 // Unique returns a unique string representing the reference that can be used as a key in maps. 288 func (ref *Ref) Unique() string { 289 return fmt.Sprintf("%s/%s", ref.Type.Name, strings.Join(ref.PrimaryKey, "/")) 290 } 291 292 // Resolve resolves the reference using the given find function. 293 func (ref *Ref) Resolve(find func(assertType *AssertionType, headers map[string]string) (Assertion, error)) (Assertion, error) { 294 headers, err := HeadersFromPrimaryKey(ref.Type, ref.PrimaryKey) 295 if err != nil { 296 return nil, fmt.Errorf("%q assertion reference primary key has the wrong length (expected %v): %v", ref.Type.Name, ref.Type.PrimaryKey, ref.PrimaryKey) 297 } 298 return find(ref.Type, headers) 299 } 300 301 const RevisionNotKnown = -1 302 303 // AtRevision represents an assertion at a given revision, possibly 304 // not known (RevisionNotKnown). 305 type AtRevision struct { 306 Ref 307 Revision int 308 } 309 310 func (at *AtRevision) String() string { 311 s := at.Ref.String() 312 if at.Revision == RevisionNotKnown { 313 return s 314 } 315 return fmt.Sprintf("%s at revision %d", s, at.Revision) 316 } 317 318 // AtSequence references a sequence forming assertion at a given sequence point, 319 // possibly <=0 (meaning not specified) and revision, possibly not known 320 // (RevisionNotKnown). 321 // Setting Pinned = true means pinning at the given sequence point (which must be 322 // set, i.e. > 0). Pinned sequence forming assertion will be updated to the 323 // latest revision at the specified sequence point. 324 type AtSequence struct { 325 Type *AssertionType 326 SequenceKey []string 327 Sequence int 328 Pinned bool 329 Revision int 330 } 331 332 // Unique returns a unique string representing the sequence by its sequence key 333 // that can be used as a key in maps. 334 func (at *AtSequence) Unique() string { 335 return fmt.Sprintf("%s/%s", at.Type.Name, strings.Join(at.SequenceKey, "/")) 336 } 337 338 func (at *AtSequence) String() string { 339 var pkStr string 340 if len(at.SequenceKey) != len(at.Type.PrimaryKey)-1 { 341 pkStr = "???" 342 } else { 343 n := 0 344 // omit series if present in the primary key 345 if at.Type.PrimaryKey[0] == "series" { 346 n++ 347 } 348 pkStr = strings.Join(at.SequenceKey[n:], "/") 349 if at.Sequence > 0 { 350 sep := "/" 351 if at.Pinned { 352 sep = "=" 353 } 354 pkStr = fmt.Sprintf("%s%s%d", pkStr, sep, at.Sequence) 355 } 356 } 357 sk := fmt.Sprintf("%s %s", at.Type.Name, pkStr) 358 if at.Revision == RevisionNotKnown { 359 return sk 360 } 361 return fmt.Sprintf("%s at revision %d", sk, at.Revision) 362 } 363 364 // Resolve resolves the sequence with known sequence number using the given find function. 365 func (at *AtSequence) Resolve(find func(assertType *AssertionType, headers map[string]string) (Assertion, error)) (Assertion, error) { 366 if at.Sequence <= 0 { 367 hdrs, err := HeadersFromSequenceKey(at.Type, at.SequenceKey) 368 if err != nil { 369 return nil, fmt.Errorf("%q assertion reference sequence key %v is invalid: %v", at.Type.Name, at.SequenceKey, err) 370 } 371 return nil, &NotFoundError{ 372 Type: at.Type, 373 Headers: hdrs, 374 } 375 } 376 pkey := append(at.SequenceKey, fmt.Sprintf("%d", at.Sequence)) 377 headers, err := HeadersFromPrimaryKey(at.Type, pkey) 378 if err != nil { 379 return nil, fmt.Errorf("%q assertion reference primary key has the wrong length (expected %v): %v", at.Type.Name, at.Type.PrimaryKey, pkey) 380 } 381 return find(at.Type, headers) 382 } 383 384 // Assertion represents an assertion through its general elements. 385 type Assertion interface { 386 // Type returns the type of this assertion 387 Type() *AssertionType 388 // Format returns the format iteration of this assertion 389 Format() int 390 // SupportedFormat returns whether the assertion uses a supported 391 // format iteration. If false the assertion might have been only 392 // partially parsed. 393 SupportedFormat() bool 394 // Revision returns the revision of this assertion 395 Revision() int 396 // AuthorityID returns the authority that signed this assertion 397 AuthorityID() string 398 399 // Header retrieves the header with name 400 Header(name string) interface{} 401 402 // Headers returns the complete headers 403 Headers() map[string]interface{} 404 405 // HeaderString retrieves the string value of header with name or "" 406 HeaderString(name string) string 407 408 // Body returns the body of this assertion 409 Body() []byte 410 411 // Signature returns the signed content and its unprocessed signature 412 Signature() (content, signature []byte) 413 414 // SignKeyID returns the key id for the key that signed this assertion. 415 SignKeyID() string 416 417 // Prerequisites returns references to the prerequisite assertions for the validity of this one. 418 Prerequisites() []*Ref 419 420 // Ref returns a reference representing this assertion. 421 Ref() *Ref 422 423 // At returns an AtRevision referencing this assertion at its revision. 424 At() *AtRevision 425 } 426 427 // SequenceMember is implemented by assertions of sequence forming types. 428 type SequenceMember interface { 429 Assertion 430 431 // Sequence returns the sequence number of this assertion. 432 Sequence() int 433 } 434 435 // customSigner represents an assertion with special arrangements for its signing key (e.g. self-signed), rather than the usual case where an assertion is signed by its authority. 436 type customSigner interface { 437 // signKey returns the public key material for the key that signed this assertion. See also SignKeyID. 438 signKey() PublicKey 439 } 440 441 // MediaType is the media type for encoded assertions on the wire. 442 const MediaType = "application/x.ubuntu.assertion" 443 444 // assertionBase is the concrete base to hold representation data for actual assertions. 445 type assertionBase struct { 446 headers map[string]interface{} 447 body []byte 448 // parsed format iteration 449 format int 450 // parsed revision 451 revision int 452 // preserved content 453 content []byte 454 // unprocessed signature 455 signature []byte 456 } 457 458 // HeaderString retrieves the string value of header with name or "" 459 func (ab *assertionBase) HeaderString(name string) string { 460 s, _ := ab.headers[name].(string) 461 return s 462 } 463 464 // Type returns the assertion type. 465 func (ab *assertionBase) Type() *AssertionType { 466 return Type(ab.HeaderString("type")) 467 } 468 469 // Format returns the assertion format iteration. 470 func (ab *assertionBase) Format() int { 471 return ab.format 472 } 473 474 // SupportedFormat returns whether the assertion uses a supported 475 // format iteration. If false the assertion might have been only 476 // partially parsed. 477 func (ab *assertionBase) SupportedFormat() bool { 478 return ab.format <= maxSupportedFormat[ab.HeaderString("type")] 479 } 480 481 // Revision returns the assertion revision. 482 func (ab *assertionBase) Revision() int { 483 return ab.revision 484 } 485 486 // AuthorityID returns the authority-id a.k.a the signer id of the assertion. 487 func (ab *assertionBase) AuthorityID() string { 488 return ab.HeaderString("authority-id") 489 } 490 491 // Header returns the value of an header by name. 492 func (ab *assertionBase) Header(name string) interface{} { 493 v := ab.headers[name] 494 if v == nil { 495 return nil 496 } 497 return copyHeader(v) 498 } 499 500 // Headers returns the complete headers. 501 func (ab *assertionBase) Headers() map[string]interface{} { 502 return copyHeaders(ab.headers) 503 } 504 505 // Body returns the body of the assertion. 506 func (ab *assertionBase) Body() []byte { 507 return ab.body 508 } 509 510 // Signature returns the signed content and its unprocessed signature. 511 func (ab *assertionBase) Signature() (content, signature []byte) { 512 return ab.content, ab.signature 513 } 514 515 // SignKeyID returns the key id for the key that signed this assertion. 516 func (ab *assertionBase) SignKeyID() string { 517 return ab.HeaderString("sign-key-sha3-384") 518 } 519 520 // Prerequisites returns references to the prerequisite assertions for the validity of this one. 521 func (ab *assertionBase) Prerequisites() []*Ref { 522 return nil 523 } 524 525 // Ref returns a reference representing this assertion. 526 func (ab *assertionBase) Ref() *Ref { 527 assertType := ab.Type() 528 primKey := make([]string, len(assertType.PrimaryKey)) 529 for i, name := range assertType.PrimaryKey { 530 primKey[i] = ab.HeaderString(name) 531 } 532 return &Ref{ 533 Type: assertType, 534 PrimaryKey: primKey, 535 } 536 } 537 538 // At returns an AtRevision referencing this assertion at its revision. 539 func (ab *assertionBase) At() *AtRevision { 540 return &AtRevision{Ref: *ab.Ref(), Revision: ab.Revision()} 541 } 542 543 // sanity check 544 var _ Assertion = (*assertionBase)(nil) 545 546 // Decode parses a serialized assertion. 547 // 548 // The expected serialisation format looks like: 549 // 550 // HEADER ("\n\n" BODY?)? "\n\n" SIGNATURE 551 // 552 // where: 553 // 554 // HEADER is a set of header entries separated by "\n" 555 // BODY can be arbitrary text, 556 // SIGNATURE is the signature 557 // 558 // Both BODY and HEADER must be UTF8. 559 // 560 // A header entry for a single line value (no '\n' in it) looks like: 561 // 562 // NAME ": " SIMPLEVALUE 563 // 564 // The format supports multiline text values (with '\n's in them) and 565 // lists or maps, possibly nested, with string scalars in them. 566 // 567 // For those a header entry looks like: 568 // 569 // NAME ":\n" MULTI(baseindent) 570 // 571 // where MULTI can be 572 // 573 // * (baseindent + 4)-space indented value (multiline text) 574 // 575 // * entries of a list each of the form: 576 // 577 // " "*baseindent " -" ( " " SIMPLEVALUE | "\n" MULTI ) 578 // 579 // * entries of map each of the form: 580 // 581 // " "*baseindent " " NAME ":" ( " " SIMPLEVALUE | "\n" MULTI ) 582 // 583 // baseindent starts at 0 and then grows with nesting matching the 584 // previous level introduction (e.g. the " "*baseindent " -" bit) 585 // length minus 1. 586 // 587 // In general the following headers are mandatory: 588 // 589 // type 590 // authority-id (except for on the wire/self-signed assertions like serial-request) 591 // 592 // Further for a given assertion type all the primary key headers 593 // must be non empty and must not contain '/'. 594 // 595 // The following headers expect string representing integer values and 596 // if omitted otherwise are assumed to be 0: 597 // 598 // revision (a positive int) 599 // body-length (expected to be equal to the length of BODY) 600 // format (a positive int for the format iteration of the type used) 601 // 602 // Times are expected to be in the RFC3339 format: "2006-01-02T15:04:05Z07:00". 603 // 604 func Decode(serializedAssertion []byte) (Assertion, error) { 605 // copy to get an independent backstorage that can't be mutated later 606 assertionSnapshot := make([]byte, len(serializedAssertion)) 607 copy(assertionSnapshot, serializedAssertion) 608 contentSignatureSplit := bytes.LastIndex(assertionSnapshot, nlnl) 609 if contentSignatureSplit == -1 { 610 return nil, fmt.Errorf("assertion content/signature separator not found") 611 } 612 content := assertionSnapshot[:contentSignatureSplit] 613 signature := assertionSnapshot[contentSignatureSplit+2:] 614 615 headersBodySplit := bytes.Index(content, nlnl) 616 var body, head []byte 617 if headersBodySplit == -1 { 618 head = content 619 } else { 620 body = content[headersBodySplit+2:] 621 if len(body) == 0 { 622 body = nil 623 } 624 head = content[:headersBodySplit] 625 } 626 627 headers, err := parseHeaders(head) 628 if err != nil { 629 return nil, fmt.Errorf("parsing assertion headers: %v", err) 630 } 631 632 return assemble(headers, body, content, signature) 633 } 634 635 // Maximum assertion component sizes. 636 const ( 637 MaxBodySize = 2 * 1024 * 1024 638 MaxHeadersSize = 128 * 1024 639 MaxSignatureSize = 128 * 1024 640 ) 641 642 // Decoder parses a stream of assertions bundled by separating them with double newlines. 643 type Decoder struct { 644 rd io.Reader 645 initialBufSize int 646 b *bufio.Reader 647 err error 648 maxHeadersSize int 649 maxSigSize int 650 651 defaultMaxBodySize int 652 typeMaxBodySize map[*AssertionType]int 653 } 654 655 // initBuffer finishes a Decoder initialization by setting up the bufio.Reader, 656 // it returns the *Decoder for convenience of notation. 657 func (d *Decoder) initBuffer() *Decoder { 658 d.b = bufio.NewReaderSize(d.rd, d.initialBufSize) 659 return d 660 } 661 662 const defaultDecoderBufSize = 4096 663 664 // NewDecoder returns a Decoder to parse the stream of assertions from the reader. 665 func NewDecoder(r io.Reader) *Decoder { 666 return (&Decoder{ 667 rd: r, 668 initialBufSize: defaultDecoderBufSize, 669 maxHeadersSize: MaxHeadersSize, 670 maxSigSize: MaxSignatureSize, 671 defaultMaxBodySize: MaxBodySize, 672 }).initBuffer() 673 } 674 675 // NewDecoderWithTypeMaxBodySize returns a Decoder to parse the stream of assertions from the reader enforcing optional per type max body sizes or the default one as fallback. 676 func NewDecoderWithTypeMaxBodySize(r io.Reader, typeMaxBodySize map[*AssertionType]int) *Decoder { 677 return (&Decoder{ 678 rd: r, 679 initialBufSize: defaultDecoderBufSize, 680 maxHeadersSize: MaxHeadersSize, 681 maxSigSize: MaxSignatureSize, 682 defaultMaxBodySize: MaxBodySize, 683 typeMaxBodySize: typeMaxBodySize, 684 }).initBuffer() 685 } 686 687 func (d *Decoder) peek(size int) ([]byte, error) { 688 buf, err := d.b.Peek(size) 689 if err == bufio.ErrBufferFull { 690 rebuf, reerr := d.b.Peek(d.b.Buffered()) 691 if reerr != nil { 692 panic(reerr) 693 } 694 mr := io.MultiReader(bytes.NewBuffer(rebuf), d.rd) 695 d.b = bufio.NewReaderSize(mr, (size/d.initialBufSize+1)*d.initialBufSize) 696 buf, err = d.b.Peek(size) 697 } 698 if err != nil && d.err == nil { 699 d.err = err 700 } 701 return buf, d.err 702 } 703 704 // NB: readExact and readUntil use peek underneath and their returned 705 // buffers are valid only until the next reading call 706 707 func (d *Decoder) readExact(size int) ([]byte, error) { 708 buf, err := d.peek(size) 709 d.b.Discard(len(buf)) 710 if len(buf) == size { 711 return buf, nil 712 } 713 if err == io.EOF { 714 return buf, io.ErrUnexpectedEOF 715 } 716 return buf, err 717 } 718 719 func (d *Decoder) readUntil(delim []byte, maxSize int) ([]byte, error) { 720 last := 0 721 size := d.initialBufSize 722 for { 723 buf, err := d.peek(size) 724 if i := bytes.Index(buf[last:], delim); i >= 0 { 725 d.b.Discard(last + i + len(delim)) 726 return buf[:last+i+len(delim)], nil 727 } 728 // report errors only once we have consumed what is buffered 729 if err != nil && len(buf) == d.b.Buffered() { 730 d.b.Discard(len(buf)) 731 return buf, err 732 } 733 last = size - len(delim) + 1 734 size *= 2 735 if size > maxSize { 736 return nil, fmt.Errorf("maximum size exceeded while looking for delimiter %q", delim) 737 } 738 } 739 } 740 741 // Decode parses the next assertion from the stream. 742 // It returns the error io.EOF at the end of a well-formed stream. 743 func (d *Decoder) Decode() (Assertion, error) { 744 // read the headers and the nlnl separator after them 745 headAndSep, err := d.readUntil(nlnl, d.maxHeadersSize) 746 if err != nil { 747 if err == io.EOF { 748 if len(headAndSep) != 0 { 749 return nil, io.ErrUnexpectedEOF 750 } 751 return nil, io.EOF 752 } 753 return nil, fmt.Errorf("error reading assertion headers: %v", err) 754 } 755 756 headLen := len(headAndSep) - len(nlnl) 757 headers, err := parseHeaders(headAndSep[:headLen]) 758 if err != nil { 759 return nil, fmt.Errorf("parsing assertion headers: %v", err) 760 } 761 762 typeStr, _ := headers["type"].(string) 763 typ := Type(typeStr) 764 765 length, err := checkIntWithDefault(headers, "body-length", 0) 766 if err != nil { 767 return nil, fmt.Errorf("assertion: %v", err) 768 } 769 if typMaxBodySize := d.typeMaxBodySize[typ]; typMaxBodySize != 0 && length > typMaxBodySize { 770 return nil, fmt.Errorf("assertion body length %d exceeds maximum body size %d for %q assertions", length, typMaxBodySize, typ.Name) 771 } else if length > d.defaultMaxBodySize { 772 return nil, fmt.Errorf("assertion body length %d exceeds maximum body size", length) 773 } 774 775 // save the headers before we try to read more, and setup to capture 776 // the whole content in a buffer 777 contentBuf := bytes.NewBuffer(make([]byte, 0, len(headAndSep)+length)) 778 contentBuf.Write(headAndSep) 779 780 if length > 0 { 781 // read the body if length != 0 782 body, err := d.readExact(length) 783 if err != nil { 784 return nil, err 785 } 786 contentBuf.Write(body) 787 } 788 789 // try to read the end of body a.k.a content/signature separator 790 endOfBody, err := d.readUntil(nlnl, d.maxSigSize) 791 if err != nil && err != io.EOF { 792 return nil, fmt.Errorf("error reading assertion trailer: %v", err) 793 } 794 795 var sig []byte 796 if bytes.Equal(endOfBody, nlnl) { 797 // we got the nlnl content/signature separator, read the signature now and the assertion/assertion nlnl separation 798 sig, err = d.readUntil(nlnl, d.maxSigSize) 799 if err != nil && err != io.EOF { 800 return nil, fmt.Errorf("error reading assertion signature: %v", err) 801 } 802 } else { 803 // we got the signature directly which is a ok format only if body length == 0 804 if length > 0 { 805 return nil, fmt.Errorf("missing content/signature separator") 806 } 807 sig = endOfBody 808 contentBuf.Truncate(headLen) 809 } 810 811 // normalize sig ending newlines 812 if bytes.HasSuffix(sig, nlnl) { 813 sig = sig[:len(sig)-1] 814 } 815 816 finalContent := contentBuf.Bytes() 817 var finalBody []byte 818 if length > 0 { 819 finalBody = finalContent[headLen+len(nlnl):] 820 } 821 822 finalSig := make([]byte, len(sig)) 823 copy(finalSig, sig) 824 825 return assemble(headers, finalBody, finalContent, finalSig) 826 } 827 828 func checkIteration(headers map[string]interface{}, name string) (int, error) { 829 iternum, err := checkIntWithDefault(headers, name, 0) 830 if err != nil { 831 return -1, err 832 } 833 if iternum < 0 { 834 return -1, fmt.Errorf("%s should be positive: %v", name, iternum) 835 } 836 return iternum, nil 837 } 838 839 func checkFormat(headers map[string]interface{}) (int, error) { 840 return checkIteration(headers, "format") 841 } 842 843 func checkRevision(headers map[string]interface{}) (int, error) { 844 return checkIteration(headers, "revision") 845 } 846 847 // Assemble assembles an assertion from its components. 848 func Assemble(headers map[string]interface{}, body, content, signature []byte) (Assertion, error) { 849 err := checkHeaders(headers) 850 if err != nil { 851 return nil, err 852 } 853 return assemble(headers, body, content, signature) 854 } 855 856 // assemble is the internal variant of Assemble, assumes headers are already checked for supported types 857 func assemble(headers map[string]interface{}, body, content, signature []byte) (Assertion, error) { 858 length, err := checkIntWithDefault(headers, "body-length", 0) 859 if err != nil { 860 return nil, fmt.Errorf("assertion: %v", err) 861 } 862 if length != len(body) { 863 return nil, fmt.Errorf("assertion body length and declared body-length don't match: %v != %v", len(body), length) 864 } 865 866 if !utf8.Valid(body) { 867 return nil, fmt.Errorf("body is not utf8") 868 } 869 870 if _, err := checkDigest(headers, "sign-key-sha3-384", crypto.SHA3_384); err != nil { 871 return nil, fmt.Errorf("assertion: %v", err) 872 } 873 874 typ, err := checkNotEmptyString(headers, "type") 875 if err != nil { 876 return nil, fmt.Errorf("assertion: %v", err) 877 } 878 assertType := Type(typ) 879 if assertType == nil { 880 return nil, fmt.Errorf("unknown assertion type: %q", typ) 881 } 882 883 if assertType.flags&noAuthority == 0 { 884 if _, err := checkNotEmptyString(headers, "authority-id"); err != nil { 885 return nil, fmt.Errorf("assertion: %v", err) 886 } 887 } else { 888 _, ok := headers["authority-id"] 889 if ok { 890 return nil, fmt.Errorf("%q assertion cannot have authority-id set", assertType.Name) 891 } 892 } 893 894 formatnum, err := checkFormat(headers) 895 if err != nil { 896 return nil, fmt.Errorf("assertion: %v", err) 897 } 898 899 for _, primKey := range assertType.PrimaryKey { 900 if _, err := checkPrimaryKey(headers, primKey); err != nil { 901 return nil, fmt.Errorf("assertion %s: %v", assertType.Name, err) 902 } 903 } 904 905 revision, err := checkRevision(headers) 906 if err != nil { 907 return nil, fmt.Errorf("assertion: %v", err) 908 } 909 910 if len(signature) == 0 { 911 return nil, fmt.Errorf("empty assertion signature") 912 } 913 914 assert, err := assertType.assembler(assertionBase{ 915 headers: headers, 916 body: body, 917 format: formatnum, 918 revision: revision, 919 content: content, 920 signature: signature, 921 }) 922 if err != nil { 923 return nil, fmt.Errorf("assertion %s: %v", assertType.Name, err) 924 } 925 return assert, nil 926 } 927 928 func writeHeader(buf *bytes.Buffer, headers map[string]interface{}, name string) { 929 appendEntry(buf, fmt.Sprintf("%s:", name), headers[name], 0) 930 } 931 932 func assembleAndSign(assertType *AssertionType, headers map[string]interface{}, body []byte, privKey PrivateKey) (Assertion, error) { 933 err := checkAssertType(assertType) 934 if err != nil { 935 return nil, err 936 } 937 938 withAuthority := assertType.flags&noAuthority == 0 939 940 err = checkHeaders(headers) 941 if err != nil { 942 return nil, err 943 } 944 945 // there's no hint at all that we will need non-textual bodies, 946 // make sure we actually enforce that 947 if !utf8.Valid(body) { 948 return nil, fmt.Errorf("assertion body is not utf8") 949 } 950 951 finalHeaders := copyHeaders(headers) 952 bodyLength := len(body) 953 finalBody := make([]byte, bodyLength) 954 copy(finalBody, body) 955 finalHeaders["type"] = assertType.Name 956 finalHeaders["body-length"] = strconv.Itoa(bodyLength) 957 finalHeaders["sign-key-sha3-384"] = privKey.PublicKey().ID() 958 959 if withAuthority { 960 if _, err := checkNotEmptyString(finalHeaders, "authority-id"); err != nil { 961 return nil, err 962 } 963 } else { 964 _, ok := finalHeaders["authority-id"] 965 if ok { 966 return nil, fmt.Errorf("%q assertion cannot have authority-id set", assertType.Name) 967 } 968 } 969 970 formatnum, err := checkFormat(finalHeaders) 971 if err != nil { 972 return nil, err 973 } 974 975 if formatnum > assertType.MaxSupportedFormat() { 976 return nil, fmt.Errorf("cannot sign %q assertion with format %d higher than max supported format %d", assertType.Name, formatnum, assertType.MaxSupportedFormat()) 977 } 978 979 suggestedFormat, err := SuggestFormat(assertType, finalHeaders, finalBody) 980 if err != nil { 981 return nil, err 982 } 983 984 if suggestedFormat > formatnum { 985 return nil, fmt.Errorf("cannot sign %q assertion with format set to %d lower than min format %d covering included features", assertType.Name, formatnum, suggestedFormat) 986 } 987 988 revision, err := checkRevision(finalHeaders) 989 if err != nil { 990 return nil, err 991 } 992 993 buf := bytes.NewBufferString("type: ") 994 buf.WriteString(assertType.Name) 995 996 if formatnum > 0 { 997 writeHeader(buf, finalHeaders, "format") 998 } else { 999 delete(finalHeaders, "format") 1000 } 1001 1002 if withAuthority { 1003 writeHeader(buf, finalHeaders, "authority-id") 1004 } 1005 1006 if revision > 0 { 1007 writeHeader(buf, finalHeaders, "revision") 1008 } else { 1009 delete(finalHeaders, "revision") 1010 } 1011 written := map[string]bool{ 1012 "type": true, 1013 "format": true, 1014 "authority-id": true, 1015 "revision": true, 1016 "body-length": true, 1017 "sign-key-sha3-384": true, 1018 } 1019 for _, primKey := range assertType.PrimaryKey { 1020 if _, err := checkPrimaryKey(finalHeaders, primKey); err != nil { 1021 return nil, err 1022 } 1023 writeHeader(buf, finalHeaders, primKey) 1024 written[primKey] = true 1025 } 1026 1027 // emit other headers in lexicographic order 1028 otherKeys := make([]string, 0, len(finalHeaders)) 1029 for name := range finalHeaders { 1030 if !written[name] { 1031 otherKeys = append(otherKeys, name) 1032 } 1033 } 1034 sort.Strings(otherKeys) 1035 for _, k := range otherKeys { 1036 writeHeader(buf, finalHeaders, k) 1037 } 1038 1039 // body-length and body 1040 if bodyLength > 0 { 1041 writeHeader(buf, finalHeaders, "body-length") 1042 } else { 1043 delete(finalHeaders, "body-length") 1044 } 1045 1046 // signing key reference 1047 writeHeader(buf, finalHeaders, "sign-key-sha3-384") 1048 1049 if bodyLength > 0 { 1050 buf.Grow(bodyLength + 2) 1051 buf.Write(nlnl) 1052 buf.Write(finalBody) 1053 } else { 1054 finalBody = nil 1055 } 1056 content := buf.Bytes() 1057 1058 signature, err := signContent(content, privKey) 1059 if err != nil { 1060 return nil, fmt.Errorf("cannot sign assertion: %v", err) 1061 } 1062 // be 'cat' friendly, add a ignored newline to the signature which is the last part of the encoded assertion 1063 signature = append(signature, '\n') 1064 1065 assert, err := assertType.assembler(assertionBase{ 1066 headers: finalHeaders, 1067 body: finalBody, 1068 format: formatnum, 1069 revision: revision, 1070 content: content, 1071 signature: signature, 1072 }) 1073 if err != nil { 1074 return nil, fmt.Errorf("cannot assemble assertion %s: %v", assertType.Name, err) 1075 } 1076 return assert, nil 1077 } 1078 1079 // SignWithoutAuthority assembles an assertion without a set authority with the provided information and signs it with the given private key. 1080 func SignWithoutAuthority(assertType *AssertionType, headers map[string]interface{}, body []byte, privKey PrivateKey) (Assertion, error) { 1081 if assertType.flags&noAuthority == 0 { 1082 return nil, fmt.Errorf("cannot sign assertions needing a definite authority with SignWithoutAuthority") 1083 } 1084 return assembleAndSign(assertType, headers, body, privKey) 1085 } 1086 1087 // Encode serializes an assertion. 1088 func Encode(assert Assertion) []byte { 1089 content, signature := assert.Signature() 1090 needed := len(content) + 2 + len(signature) 1091 buf := bytes.NewBuffer(make([]byte, 0, needed)) 1092 buf.Write(content) 1093 buf.Write(nlnl) 1094 buf.Write(signature) 1095 return buf.Bytes() 1096 } 1097 1098 // Encoder emits a stream of assertions bundled by separating them with double newlines. 1099 type Encoder struct { 1100 wr io.Writer 1101 nextSep []byte 1102 } 1103 1104 // NewEncoder returns a Encoder to emit a stream of assertions to a writer. 1105 func NewEncoder(w io.Writer) *Encoder { 1106 return &Encoder{wr: w} 1107 } 1108 1109 func (enc *Encoder) writeSep(last byte) error { 1110 if last != '\n' { 1111 _, err := enc.wr.Write(nl) 1112 if err != nil { 1113 return err 1114 } 1115 } 1116 enc.nextSep = nl 1117 return nil 1118 } 1119 1120 // WriteEncoded writes the encoded assertion into the stream with the required separator. 1121 func (enc *Encoder) WriteEncoded(encoded []byte) error { 1122 sz := len(encoded) 1123 if sz == 0 { 1124 return fmt.Errorf("internal error: encoded assertion cannot be empty") 1125 } 1126 1127 _, err := enc.wr.Write(enc.nextSep) 1128 if err != nil { 1129 return err 1130 } 1131 1132 _, err = enc.wr.Write(encoded) 1133 if err != nil { 1134 return err 1135 } 1136 1137 return enc.writeSep(encoded[sz-1]) 1138 } 1139 1140 // WriteContentSignature writes the content and signature of an assertion into the stream with all the required separators. 1141 func (enc *Encoder) WriteContentSignature(content, signature []byte) error { 1142 if len(content) == 0 { 1143 return fmt.Errorf("internal error: content cannot be empty") 1144 } 1145 1146 sz := len(signature) 1147 if sz == 0 { 1148 return fmt.Errorf("internal error: signature cannot be empty") 1149 } 1150 1151 _, err := enc.wr.Write(enc.nextSep) 1152 if err != nil { 1153 return err 1154 } 1155 1156 _, err = enc.wr.Write(content) 1157 if err != nil { 1158 return err 1159 } 1160 _, err = enc.wr.Write(nlnl) 1161 if err != nil { 1162 return err 1163 } 1164 _, err = enc.wr.Write(signature) 1165 if err != nil { 1166 return err 1167 } 1168 1169 return enc.writeSep(signature[sz-1]) 1170 } 1171 1172 // Encode emits the assertion into the stream with the required separator. 1173 // Errors here are always about writing given that Encode() itself cannot error. 1174 func (enc *Encoder) Encode(assert Assertion) error { 1175 return enc.WriteContentSignature(assert.Signature()) 1176 } 1177 1178 // SignatureCheck checks the signature of the assertion against the given public key. Useful for assertions with no authority. 1179 func SignatureCheck(assert Assertion, pubKey PublicKey) error { 1180 content, encodedSig := assert.Signature() 1181 sig, err := decodeSignature(encodedSig) 1182 if err != nil { 1183 return err 1184 } 1185 err = pubKey.verify(content, sig) 1186 if err != nil { 1187 return fmt.Errorf("failed signature verification: %v", err) 1188 } 1189 return nil 1190 }