(ext []byte)
| 523 | ) |
| 524 | |
| 525 | func parseECHExt(ext []byte) (echType echExtType, cs EchCipher, configID uint8, encap []byte, payload []byte, err error) { |
| 526 | data := make([]byte, len(ext)) |
| 527 | copy(data, ext) |
| 528 | s := cryptobyte.String(data) |
| 529 | var echInt uint8 |
| 530 | if !s.ReadUint8(&echInt) { |
| 531 | err = errMalformedECHExt |
| 532 | return |
| 533 | } |
| 534 | echType = echExtType(echInt) |
| 535 | if echType == innerECHExt { |
| 536 | if !s.Empty() { |
| 537 | err = errMalformedECHExt |
| 538 | return |
| 539 | } |
| 540 | return echType, cs, 0, nil, nil, nil |
| 541 | } |
| 542 | if echType != outerECHExt { |
| 543 | err = errInvalidECHExt |
| 544 | return |
| 545 | } |
| 546 | if !s.ReadUint16(&cs.KDFID) { |
| 547 | err = errMalformedECHExt |
| 548 | return |
| 549 | } |
| 550 | if !s.ReadUint16(&cs.AEADID) { |
| 551 | err = errMalformedECHExt |
| 552 | return |
| 553 | } |
| 554 | if !s.ReadUint8(&configID) { |
| 555 | err = errMalformedECHExt |
| 556 | return |
| 557 | } |
| 558 | if !readUint16LengthPrefixed(&s, &encap) { |
| 559 | err = errMalformedECHExt |
| 560 | return |
| 561 | } |
| 562 | if !readUint16LengthPrefixed(&s, &payload) { |
| 563 | err = errMalformedECHExt |
| 564 | return |
| 565 | } |
| 566 | |
| 567 | // NOTE: clone encap and payload so that mutating them does not mutate the |
| 568 | // raw extension bytes. |
| 569 | return echType, cs, configID, bytes.Clone(encap), bytes.Clone(payload), nil |
| 570 | } |
| 571 | |
| 572 | func marshalEncryptedClientHelloConfigList(configs []EncryptedClientHelloKey) ([]byte, error) { |
| 573 | builder := cryptobyte.NewBuilder(nil) |
no test coverage detected
searching dependent graphs…