alert.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. // Package alert implements TLS alert protocol https://tools.ietf.org/html/rfc5246#section-7.2
  4. package alert
  5. import (
  6. "errors"
  7. "fmt"
  8. "github.com/pion/dtls/v2/pkg/protocol"
  9. )
  10. var errBufferTooSmall = &protocol.TemporaryError{Err: errors.New("buffer is too small")} //nolint:goerr113
  11. // Level is the level of the TLS Alert
  12. type Level byte
  13. // Level enums
  14. const (
  15. Warning Level = 1
  16. Fatal Level = 2
  17. )
  18. func (l Level) String() string {
  19. switch l {
  20. case Warning:
  21. return "Warning"
  22. case Fatal:
  23. return "Fatal"
  24. default:
  25. return "Invalid alert level"
  26. }
  27. }
  28. // Description is the extended info of the TLS Alert
  29. type Description byte
  30. // Description enums
  31. const (
  32. CloseNotify Description = 0
  33. UnexpectedMessage Description = 10
  34. BadRecordMac Description = 20
  35. DecryptionFailed Description = 21
  36. RecordOverflow Description = 22
  37. DecompressionFailure Description = 30
  38. HandshakeFailure Description = 40
  39. NoCertificate Description = 41
  40. BadCertificate Description = 42
  41. UnsupportedCertificate Description = 43
  42. CertificateRevoked Description = 44
  43. CertificateExpired Description = 45
  44. CertificateUnknown Description = 46
  45. IllegalParameter Description = 47
  46. UnknownCA Description = 48
  47. AccessDenied Description = 49
  48. DecodeError Description = 50
  49. DecryptError Description = 51
  50. ExportRestriction Description = 60
  51. ProtocolVersion Description = 70
  52. InsufficientSecurity Description = 71
  53. InternalError Description = 80
  54. UserCanceled Description = 90
  55. NoRenegotiation Description = 100
  56. UnsupportedExtension Description = 110
  57. NoApplicationProtocol Description = 120
  58. )
  59. func (d Description) String() string {
  60. switch d {
  61. case CloseNotify:
  62. return "CloseNotify"
  63. case UnexpectedMessage:
  64. return "UnexpectedMessage"
  65. case BadRecordMac:
  66. return "BadRecordMac"
  67. case DecryptionFailed:
  68. return "DecryptionFailed"
  69. case RecordOverflow:
  70. return "RecordOverflow"
  71. case DecompressionFailure:
  72. return "DecompressionFailure"
  73. case HandshakeFailure:
  74. return "HandshakeFailure"
  75. case NoCertificate:
  76. return "NoCertificate"
  77. case BadCertificate:
  78. return "BadCertificate"
  79. case UnsupportedCertificate:
  80. return "UnsupportedCertificate"
  81. case CertificateRevoked:
  82. return "CertificateRevoked"
  83. case CertificateExpired:
  84. return "CertificateExpired"
  85. case CertificateUnknown:
  86. return "CertificateUnknown"
  87. case IllegalParameter:
  88. return "IllegalParameter"
  89. case UnknownCA:
  90. return "UnknownCA"
  91. case AccessDenied:
  92. return "AccessDenied"
  93. case DecodeError:
  94. return "DecodeError"
  95. case DecryptError:
  96. return "DecryptError"
  97. case ExportRestriction:
  98. return "ExportRestriction"
  99. case ProtocolVersion:
  100. return "ProtocolVersion"
  101. case InsufficientSecurity:
  102. return "InsufficientSecurity"
  103. case InternalError:
  104. return "InternalError"
  105. case UserCanceled:
  106. return "UserCanceled"
  107. case NoRenegotiation:
  108. return "NoRenegotiation"
  109. case UnsupportedExtension:
  110. return "UnsupportedExtension"
  111. case NoApplicationProtocol:
  112. return "NoApplicationProtocol"
  113. default:
  114. return "Invalid alert description"
  115. }
  116. }
  117. // Alert is one of the content types supported by the TLS record layer.
  118. // Alert messages convey the severity of the message
  119. // (warning or fatal) and a description of the alert. Alert messages
  120. // with a level of fatal result in the immediate termination of the
  121. // connection. In this case, other connections corresponding to the
  122. // session may continue, but the session identifier MUST be invalidated,
  123. // preventing the failed session from being used to establish new
  124. // connections. Like other messages, alert messages are encrypted and
  125. // compressed, as specified by the current connection state.
  126. // https://tools.ietf.org/html/rfc5246#section-7.2
  127. type Alert struct {
  128. Level Level
  129. Description Description
  130. }
  131. // ContentType returns the ContentType of this Content
  132. func (a Alert) ContentType() protocol.ContentType {
  133. return protocol.ContentTypeAlert
  134. }
  135. // Marshal returns the encoded alert
  136. func (a *Alert) Marshal() ([]byte, error) {
  137. return []byte{byte(a.Level), byte(a.Description)}, nil
  138. }
  139. // Unmarshal populates the alert from binary data
  140. func (a *Alert) Unmarshal(data []byte) error {
  141. if len(data) != 2 {
  142. return errBufferTooSmall
  143. }
  144. a.Level = Level(data[0])
  145. a.Description = Description(data[1])
  146. return nil
  147. }
  148. func (a *Alert) String() string {
  149. return fmt.Sprintf("Alert %s: %s", a.Level, a.Description)
  150. }