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