example_test.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Copyright 2017 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package cryptobyte_test
  5. import (
  6. "encoding/asn1"
  7. "fmt"
  8. "golang.org/x/crypto/cryptobyte"
  9. )
  10. func ExampleString_lengthPrefixed() {
  11. // This is an example of parsing length-prefixed data (as found in, for
  12. // example, TLS). Imagine a 16-bit prefixed series of 8-bit prefixed
  13. // strings.
  14. input := cryptobyte.String([]byte{0, 12, 5, 'h', 'e', 'l', 'l', 'o', 5, 'w', 'o', 'r', 'l', 'd'})
  15. var result []string
  16. var values cryptobyte.String
  17. if !input.ReadUint16LengthPrefixed(&values) ||
  18. !input.Empty() {
  19. panic("bad format")
  20. }
  21. for !values.Empty() {
  22. var value cryptobyte.String
  23. if !values.ReadUint8LengthPrefixed(&value) {
  24. panic("bad format")
  25. }
  26. result = append(result, string(value))
  27. }
  28. // Output: []string{"hello", "world"}
  29. fmt.Printf("%#v\n", result)
  30. }
  31. func ExampleString_asn1() {
  32. // This is an example of parsing ASN.1 data that looks like:
  33. // Foo ::= SEQUENCE {
  34. // version [6] INTEGER DEFAULT 0
  35. // data OCTET STRING
  36. // }
  37. input := cryptobyte.String([]byte{0x30, 12, 0xa6, 3, 2, 1, 2, 4, 5, 'h', 'e', 'l', 'l', 'o'})
  38. var (
  39. version int64
  40. data, inner, versionBytes cryptobyte.String
  41. haveVersion bool
  42. )
  43. if !input.ReadASN1(&inner, cryptobyte.Tag(asn1.TagSequence).Constructed()) ||
  44. !input.Empty() ||
  45. !inner.ReadOptionalASN1(&versionBytes, &haveVersion, cryptobyte.Tag(6).Constructed().ContextSpecific()) ||
  46. (haveVersion && !versionBytes.ReadASN1Integer(&version)) ||
  47. (haveVersion && !versionBytes.Empty()) ||
  48. !inner.ReadASN1(&data, asn1.TagOctetString) ||
  49. !inner.Empty() {
  50. panic("bad format")
  51. }
  52. // Output: haveVersion: true, version: 2, data: hello
  53. fmt.Printf("haveVersion: %t, version: %d, data: %s\n", haveVersion, version, string(data))
  54. }
  55. func ExampleBuilder_asn1() {
  56. // This is an example of building ASN.1 data that looks like:
  57. // Foo ::= SEQUENCE {
  58. // version [6] INTEGER DEFAULT 0
  59. // data OCTET STRING
  60. // }
  61. version := int64(2)
  62. data := []byte("hello")
  63. const defaultVersion = 0
  64. var b cryptobyte.Builder
  65. b.AddASN1(cryptobyte.Tag(asn1.TagSequence).Constructed(), func(b *cryptobyte.Builder) {
  66. if version != defaultVersion {
  67. b.AddASN1(cryptobyte.Tag(6).Constructed().ContextSpecific(), func(b *cryptobyte.Builder) {
  68. b.AddASN1Int64(version)
  69. })
  70. }
  71. b.AddASN1OctetString(data)
  72. })
  73. result, err := b.Bytes()
  74. if err != nil {
  75. panic(err)
  76. }
  77. // Output: 300ca603020102040568656c6c6f
  78. fmt.Printf("%x\n", result)
  79. }
  80. func ExampleBuilder_lengthPrefixed() {
  81. // This is an example of building length-prefixed data (as found in,
  82. // for example, TLS). Imagine a 16-bit prefixed series of 8-bit
  83. // prefixed strings.
  84. input := []string{"hello", "world"}
  85. var b cryptobyte.Builder
  86. b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
  87. for _, value := range input {
  88. b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
  89. b.AddBytes([]byte(value))
  90. })
  91. }
  92. })
  93. result, err := b.Bytes()
  94. if err != nil {
  95. panic(err)
  96. }
  97. // Output: 000c0568656c6c6f05776f726c64
  98. fmt.Printf("%x\n", result)
  99. }