github.com/pion/dtls/v2@v2.2.12/pkg/protocol/alert/alert.go (about)

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