blob: 47754d738a43b8f2057093defcbe325cb2dd89ab [file] [log] [blame]
Holger Hildebrandtfa074992020-03-27 15:42:06 +00001// Package gssapi implements Generic Security Services Application Program Interface required for SPNEGO kerberos authentication.
2package gssapi
3
4import (
5 "context"
6 "fmt"
7
8 "github.com/jcmturner/gofork/encoding/asn1"
9)
10
11// GSS-API OID names
12const (
13 // GSS-API OID names
14 OIDKRB5 OIDName = "KRB5" // MechType OID for Kerberos 5
15 OIDMSLegacyKRB5 OIDName = "MSLegacyKRB5" // MechType OID for Kerberos 5
16 OIDSPNEGO OIDName = "SPNEGO"
17)
18
19// GSS-API status values
20const (
21 StatusBadBindings = 1 << iota
22 StatusBadMech
23 StatusBadName
24 StatusBadNameType
25 StatusBadStatus
26 StatusBadSig
27 StatusBadMIC
28 StatusContextExpired
29 StatusCredentialsExpired
30 StatusDefectiveCredential
31 StatusDefectiveToken
32 StatusFailure
33 StatusNoContext
34 StatusNoCred
35 StatusBadQOP
36 StatusUnauthorized
37 StatusUnavailable
38 StatusDuplicateElement
39 StatusNameNotMN
40 StatusComplete
41 StatusContinueNeeded
42 StatusDuplicateToken
43 StatusOldToken
44 StatusUnseqToken
45 StatusGapToken
46)
47
48// ContextToken is an interface for a GSS-API context token.
49type ContextToken interface {
50 Marshal() ([]byte, error)
51 Unmarshal(b []byte) error
52 Verify() (bool, Status)
53 Context() context.Context
54}
55
56/*
57CREDENTIAL MANAGEMENT
58
59GSS_Acquire_cred acquire credentials for use
60GSS_Release_cred release credentials after use
61GSS_Inquire_cred display information about credentials
62GSS_Add_cred construct credentials incrementally
63GSS_Inquire_cred_by_mech display per-mechanism credential information
64
65CONTEXT-LEVEL CALLS
66
67GSS_Init_sec_context initiate outbound security context
68GSS_Accept_sec_context accept inbound security context
69GSS_Delete_sec_context flush context when no longer needed
70GSS_Process_context_token process received control token on context
71GSS_Context_time indicate validity time remaining on context
72GSS_Inquire_context display information about context
73GSS_Wrap_size_limit determine GSS_Wrap token size limit
74GSS_Export_sec_context transfer context to other process
75GSS_Import_sec_context import transferred context
76
77PER-MESSAGE CALLS
78
79GSS_GetMIC apply integrity check, receive as token separate from message
80GSS_VerifyMIC validate integrity check token along with message
81GSS_Wrap sign, optionally encrypt, encapsulate
82GSS_Unwrap decapsulate, decrypt if needed, validate integrity check
83
84SUPPORT CALLS
85
86GSS_Display_status translate status codes to printable form
87GSS_Indicate_mechs indicate mech_types supported on local system
88GSS_Compare_name compare two names for equality
89GSS_Display_name translate name to printable form
90GSS_Import_name convert printable name to normalized form
91GSS_Release_name free storage of normalized-form name
92GSS_Release_buffer free storage of general GSS-allocated object
93GSS_Release_OID_set free storage of OID set object
94GSS_Create_empty_OID_set create empty OID set
95GSS_Add_OID_set_member add member to OID set
96GSS_Test_OID_set_member test if OID is member of OID set
97GSS_Inquire_names_for_mech indicate name types supported by mechanism
98GSS_Inquire_mechs_for_name indicates mechanisms supporting name type
99GSS_Canonicalize_name translate name to per-mechanism form
100GSS_Export_name externalize per-mechanism name
101GSS_Duplicate_name duplicate name object
102*/
103
104// Mechanism is the GSS-API interface for authentication mechanisms.
105type Mechanism interface {
106 OID() asn1.ObjectIdentifier
107 AcquireCred() error // acquire credentials for use (eg. AS exchange for KRB5)
108 InitSecContext() (ContextToken, error) // initiate outbound security context (eg TGS exchange builds AP_REQ to go into ContextToken to send to service)
109 AcceptSecContext(ct ContextToken) (bool, context.Context, Status) // service verifies the token server side to establish a context
110 MIC() MICToken // apply integrity check, receive as token separate from message
111 VerifyMIC(mt MICToken) (bool, error) // validate integrity check token along with message
112 Wrap(msg []byte) WrapToken // sign, optionally encrypt, encapsulate
113 Unwrap(wt WrapToken) []byte // decapsulate, decrypt if needed, validate integrity check
114}
115
116// OIDName is the type for defined GSS-API OIDs.
117type OIDName string
118
119// OID returns the OID for the provided OID name.
120func OID(o OIDName) asn1.ObjectIdentifier {
121 switch o {
122 case OIDSPNEGO:
123 return asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 2}
124 case OIDKRB5:
125 return asn1.ObjectIdentifier{1, 2, 840, 113554, 1, 2, 2}
126 case OIDMSLegacyKRB5:
127 return asn1.ObjectIdentifier{1, 2, 840, 48018, 1, 2, 2}
128 }
129 return asn1.ObjectIdentifier{}
130}
131
132// Status is the GSS-API status and implements the error interface.
133type Status struct {
134 Code int
135 Message string
136}
137
138// Error returns the Status description.
139func (s Status) Error() string {
140 var str string
141 switch s.Code {
142 case StatusBadBindings:
143 str = "channel binding mismatch"
144 case StatusBadMech:
145 str = "unsupported mechanism requested"
146 case StatusBadName:
147 str = "invalid name provided"
148 case StatusBadNameType:
149 str = "name of unsupported type provided"
150 case StatusBadStatus:
151 str = "invalid input status selector"
152 case StatusBadSig:
153 str = "token had invalid integrity check"
154 case StatusBadMIC:
155 str = "preferred alias for GSS_S_BAD_SIG"
156 case StatusContextExpired:
157 str = "specified security context expired"
158 case StatusCredentialsExpired:
159 str = "expired credentials detected"
160 case StatusDefectiveCredential:
161 str = "defective credential detected"
162 case StatusDefectiveToken:
163 str = "defective token detected"
164 case StatusFailure:
165 str = "failure, unspecified at GSS-API level"
166 case StatusNoContext:
167 str = "no valid security context specified"
168 case StatusNoCred:
169 str = "no valid credentials provided"
170 case StatusBadQOP:
171 str = "unsupported QOP valu"
172 case StatusUnauthorized:
173 str = "operation unauthorized"
174 case StatusUnavailable:
175 str = "operation unavailable"
176 case StatusDuplicateElement:
177 str = "duplicate credential element requested"
178 case StatusNameNotMN:
179 str = "name contains multi-mechanism elements"
180 case StatusComplete:
181 str = "normal completion"
182 case StatusContinueNeeded:
183 str = "continuation call to routine required"
184 case StatusDuplicateToken:
185 str = "duplicate per-message token detected"
186 case StatusOldToken:
187 str = "timed-out per-message token detected"
188 case StatusUnseqToken:
189 str = "reordered (early) per-message token detected"
190 case StatusGapToken:
191 str = "skipped predecessor token(s) detected"
192 default:
193 str = "unknown GSS-API error status"
194 }
195 if s.Message != "" {
196 return fmt.Sprintf("%s: %s", str, s.Message)
197 }
198 return str
199}