spnego
import "github.com/TheManticoreProject/Manticore/crypto/spnego"
Index
- Constants
- Variables
- func CreateNegTokenInit(ntlmToken []byte) ([]byte, error)
- func CreateNegTokenResp(state NegState, mech asn1.ObjectIdentifier, token []byte) ([]byte, error)
- func ExtractNTLMToken(spnegoToken []byte) ([]byte, error)
- func OIDtoString(oid asn1.ObjectIdentifier) string
- func PrepareSessionSetupRequest(token []byte, useUnicode bool) []byte
- type AuthContext
- func NewAuthContext(authType AuthType, domain, username, password, workstation string, useUnicode bool) *AuthContext
- func (ctx *AuthContext) CreateAuthenticateTokenFromChallengeToken(challengeToken []byte) ([]byte, error)
- func (ctx *AuthContext) CreateNegotiateToken(negotiateFlags flags.NegotiateFlags, version *version.Version) ([]byte, error)
- func (ctx *AuthContext) GetAuthType() AuthType
- func (ctx *AuthContext) GetSessionKey() []byte
- func (ctx *AuthContext) ServerIdentity() (ServerIdentity, bool)
- func (ctx *AuthContext) SetAuthType(authType AuthType)
- func (ctx *AuthContext) SupportsExtendedSessionSecurity() bool
- type AuthType
- type NegState
- type NegTokenInit
- func NewNegTokenInit(mechTypes []asn1.ObjectIdentifier, reqFlags asn1.BitString, mechToken []byte, mechTokenMIC []byte) *NegTokenInit
- func (n *NegTokenInit) Marshal() ([]byte, error)
- func (n *NegTokenInit) SetMechToken(mechToken []byte)
- func (n *NegTokenInit) SetMechTokenNTLM(mechToken []byte)
- func (n *NegTokenInit) Unmarshal(data []byte) error
- type NegTokenResp
- func NewNegTokenResp(state NegState, mech asn1.ObjectIdentifier, responseToken []byte) *NegTokenResp
- func (n *NegTokenResp) Marshal() ([]byte, error)
- func (n *NegTokenResp) SetMechToken(responseToken []byte)
- func (n *NegTokenResp) SetMechTokenNTLM(responseToken []byte)
- func (n *NegTokenResp) Unmarshal(data []byte) (int, error)
- type SecurityBlob
- type ServerIdentity
Constants
GSS API constants
const (
GSS_API_SPNEGO = 0x60 // [APPLICATION 0]
)
Variables
OIDs for various authentication mechanisms
var (
// SPNEGO OID: 1.3.6.1.5.5.2
// iso.org.dod.internet.security.mechanism.snego
// Source: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-spng/94ccc4f8-d224-495f-8d31-4f58d1af598e
SpnegoOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 2}
// SPNegoEx OID: 1.3.6.1.4.1.311.2.2.30
// iso.org.dod.internet.private.enterprise.Microsoft.security.mechanisms.SPNegoEx
// Source: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-spng/f5edf48c-57cc-4c61-bff9-ee19b9cd059e
SPNegoExOID = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 2, 30}
// NTLM OID: 1.3.6.1.4.1.311.2.2.10
// iso.org.dod.internet.private.enterprise.Microsoft.security.mechanisms.NTLM
// Source: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/e21c0b07-8662-41b7-8853-2b9184eab0db
NtlmOID = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 2, 10}
// Kerberos OID: 1.2.840.113554.1.2.2
// iso.org.dod.internet.private.enterprise.Microsoft.security.mechanisms.Kerberos
// Source: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-spng/211417c4-11ef-46c0-a8fb-f178a51c2088
KerberosOID = asn1.ObjectIdentifier{1, 2, 840, 113554, 1, 2, 2}
)
func CreateNegTokenInit
func CreateNegTokenInit(ntlmToken []byte) ([]byte, error)
CreateNegTokenInit creates a SPNEGO NegTokenInit with the given NTLM token and marshals it. Parameters:
- ntlmToken: The NTLM token bytes to include in the SPNEGO token
Returns:
- []byte: The marshaled SPNEGO token containing the NTLM token
- error: An error if token creation fails
func CreateNegTokenResp
func CreateNegTokenResp(state NegState, mech asn1.ObjectIdentifier, token []byte) ([]byte, error)
CreateNegTokenResp creates an ASN.1 encoded SPNEGO NegTokenResp Parameters:
- state: The negotiation state
- mech: The supported mechanism OID
- token: The response token bytes
Returns:
- []byte: The encoded SPNEGO token
- error: An error if token creation fails
func ExtractNTLMToken
func ExtractNTLMToken(spnegoToken []byte) ([]byte, error)
ExtractNTLMToken extracts the NTLM token from a SPNEGO token (init or resp)
func OIDtoString
func OIDtoString(oid asn1.ObjectIdentifier) string
OIDtoString converts an OID to a human-readable string representation
func PrepareSessionSetupRequest
func PrepareSessionSetupRequest(token []byte, useUnicode bool) []byte
PrepareSessionSetupRequest prepares the SMB session setup request with SPNEGO token Parameters:
- token: The SPNEGO token bytes to prepare
- useUnicode: Whether to encode the token in UTF-16LE
Returns:
- []byte: The prepared token, encoded in UTF-16LE if useUnicode is true
type AuthContext
AuthContext holds the state for an authentication session
type AuthContext struct {
Type AuthType
Domain string
Username string
Password string
Workstation string
UseUnicode bool
// NTHash is the hex-encoded (32 hex chars) NT hash used for pass-the-hash. When set,
// the NTLM AUTHENTICATE is computed from this hash instead of Password, so a caller
// can authenticate with only the NT hash. Empty means authenticate with Password.
NTHash string
// NTLM specific fields
NTLMChallenge *challenge.ChallengeMessage
// NegotiateMessageBytes retains the raw NTLM NEGOTIATE_MESSAGE that was sent,
// so the AUTHENTICATE MIC can be computed over NEGOTIATE||CHALLENGE||AUTHENTICATE.
NegotiateMessageBytes []byte
// SessionKey is the session key derived during the most recent successful
// CreateAuthenticateTokenFromChallengeToken call. It is not transmitted on the
// wire; callers use it as the MAC key for SMB message signing. It is nil until
// authentication has produced a key (and for auth paths that do not derive one).
SessionKey []byte
}
func NewAuthContext
func NewAuthContext(authType AuthType, domain, username, password, workstation string, useUnicode bool) *AuthContext
NewAuthContext creates a new authentication context Parameters:
- authType: The type of authentication to use (NTLM or Kerberos)
- domain: The domain name for authentication
- username: The username to authenticate with
- password: The password for authentication
- workstation: The name of the client workstation
- useUnicode: Whether to use Unicode encoding
Returns:
- *AuthContext: A new authentication context initialized with the provided parameters
func (*AuthContext) CreateAuthenticateTokenFromChallengeToken
func (ctx *AuthContext) CreateAuthenticateTokenFromChallengeToken(challengeToken []byte) ([]byte, error)
CreateAuthenticateTokenFromChallengeToken processes the server’s challenge token and creates an authenticate token Parameters:
- challengeToken: The SPNEGO token containing the server’s challenge
Returns:
- []byte: The SPNEGO token containing the authenticate message
- error: An error if token processing fails
func (*AuthContext) CreateNegotiateToken
func (ctx *AuthContext) CreateNegotiateToken(negotiateFlags flags.NegotiateFlags, version *version.Version) ([]byte, error)
CreateNegotiateToken creates the initial SPNEGO token with NTLM negotiate message Parameters:
- ctx: The authentication context containing domain, username, password, and other settings
Returns:
- []byte: The SPNEGO token containing the NTLM negotiate message
- error: An error if token creation fails
func (*AuthContext) GetAuthType
func (ctx *AuthContext) GetAuthType() AuthType
GetAuthType returns the authentication type Returns:
- AuthType: The authentication type (NTLM or Kerberos) for this context
func (*AuthContext) GetSessionKey
func (ctx *AuthContext) GetSessionKey() []byte
GetSessionKey returns the session key derived during authentication, or nil if none has been derived yet.
Returns:
- []byte: The session key (MAC key for SMB signing), or nil
func (*AuthContext) ServerIdentity
func (ctx *AuthContext) ServerIdentity() (ServerIdentity, bool)
ServerIdentity extracts the server identity from the NTLM CHALLENGE processed during authentication. ok is false when no NTLM challenge has been processed yet (for example before CreateAuthenticateTokenFromChallengeToken is called, or for a non-NTLM exchange).
func (*AuthContext) SetAuthType
func (ctx *AuthContext) SetAuthType(authType AuthType)
SetAuthType sets the authentication type Parameters:
- authType: The authentication type (NTLM or Kerberos) to set
func (*AuthContext) SupportsExtendedSessionSecurity
func (ctx *AuthContext) SupportsExtendedSessionSecurity() bool
SupportsExtendedSessionSecurity reports whether the server’s NTLM CHALLENGE advertised NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY — i.e. NTLM2 / NTLMv2 session security. It returns false when no NTLM challenge has been processed.
type AuthType
AuthType represents the authentication type
type AuthType int
const (
AuthTypeNTLM AuthType = iota
AuthTypeKerberos
)
type NegState
NegState represents the negotiation state in SPNEGO
type NegState asn1.Enumerated
const (
// NegStateAcceptCompleted indicates the negotiation is complete and successful
NegStateAcceptCompleted NegState = 0
// NegStateAcceptIncomplete indicates more negotiation messages are needed
NegStateAcceptIncomplete NegState = 1
// NegStateReject indicates the negotiation has failed
NegStateReject NegState = 2
// NegStateRequestMIC indicates a MIC token is requested
NegStateRequestMIC NegState = 3
)
func (NegState) String
func (n NegState) String() string
String returns a string representation of the NegState Parameters:
- n: The NegState to convert to a string
Returns:
- string: A string representation of the NegState
type NegTokenInit
NegTokenInit is the initial SPNEGO token sent by the client wrapped in a [0] EXPLICIT context tag.
type NegTokenInit struct {
MechTypes []asn1.ObjectIdentifier `asn1:"explicit,tag:0"`
ReqFlags asn1.BitString `asn1:"explicit,optional,tag:1"`
MechToken []byte `asn1:"explicit,optional,tag:2"`
MechTokenMIC []byte `asn1:"explicit,optional,tag:3"`
}
func NewNegTokenInit
func NewNegTokenInit(mechTypes []asn1.ObjectIdentifier, reqFlags asn1.BitString, mechToken []byte, mechTokenMIC []byte) *NegTokenInit
NewNegTokenInit creates a new NegTokenInit with the specified parameters Parameters:
- mechTypes: The mechanism type identifiers to include
- reqFlags: The requested flags for the token
- mechToken: The mechanism token bytes
- mechTokenMIC: The mechanism token MIC bytes
Returns:
- *NegTokenInit: A new NegTokenInit initialized with the provided parameters
func (*NegTokenInit) Marshal
func (n *NegTokenInit) Marshal() ([]byte, error)
Marshal marshals the NegTokenInit into a byte slice Returns:
- []byte: The marshaled SPNEGO token bytes
- error: An error if marshaling fails
func (*NegTokenInit) SetMechToken
func (n *NegTokenInit) SetMechToken(mechToken []byte)
SetMechToken sets the mech token in the NegTokenInit Parameters:
- mechToken: The mechanism token bytes to set
func (*NegTokenInit) SetMechTokenNTLM
func (n *NegTokenInit) SetMechTokenNTLM(mechToken []byte)
SetMechTokenNTLM sets the NTLM token in the NegTokenInit Parameters:
- mechToken: The NTLM mechanism token bytes to set
func (*NegTokenInit) Unmarshal
func (n *NegTokenInit) Unmarshal(data []byte) error
Unmarshal unmarshals the NegTokenInit from a byte slice Parameters:
- data: The bytes to unmarshal from
Returns:
- error: An error if unmarshaling fails
type NegTokenResp
NegTokenResp is the response token sent by the server
NegTokenResp ::= SEQUENCE {
negState[0] ENUMERATED {
accept-completed(0),
accept-incomplete(1),
reject(2),
request-mic(3)
} OPTIONAL,
supportedMech[1] MechType OPTIONAL,
responseToken[2] OCTET STRING OPTIONAL,
mechListMIC[3] OCTET STRING OPTIONAL
}
type NegTokenResp struct {
NegState NegState `asn1:"optional,tag:0"`
SupportedMech asn1.ObjectIdentifier `asn1:"optional,tag:1"`
ResponseToken []byte `asn1:"optional,tag:2,octet"`
MechListMIC []byte `asn1:"optional,tag:3,octet"`
// SuppressNegState omits the [0] negState field on Marshal. A client's
// continuation token (the AUTHENTICATE) carries only the responseToken — no
// negState and no supportedMech — matching the Windows client.
SuppressNegState bool `asn1:"-"`
}
func NewNegTokenResp
func NewNegTokenResp(state NegState, mech asn1.ObjectIdentifier, responseToken []byte) *NegTokenResp
NewNegTokenResp creates a new NegTokenResp Parameters:
- state: The negotiation state
- mech: The supported mechanism OID
- responseToken: The response token bytes
Returns:
- *NegTokenResp: A new NegTokenResp instance
func (*NegTokenResp) Marshal
func (n *NegTokenResp) Marshal() ([]byte, error)
Marshal marshals the NegTokenResp into a byte slice Returns:
- []byte: The marshaled bytes
- error: An error if marshaling fails
func (*NegTokenResp) SetMechToken
func (n *NegTokenResp) SetMechToken(responseToken []byte)
SetMechToken sets the mech token in the NegTokenResp Parameters:
- responseToken: The response token bytes to set
func (*NegTokenResp) SetMechTokenNTLM
func (n *NegTokenResp) SetMechTokenNTLM(responseToken []byte)
SetMechTokenNTLM sets the NTLM token in the NegTokenResp Parameters:
- responseToken: The NTLM response token bytes to set
func (*NegTokenResp) Unmarshal
func (n *NegTokenResp) Unmarshal(data []byte) (int, error)
Unmarshal unmarshals the NegTokenResp from a byte slice Parameters:
- data: The bytes to unmarshal
Returns:
- int: The number of bytes read
- error: An error if unmarshaling fails
type SecurityBlob
SecurityBlob represents a security token wrapped in ASN.1 encoding. It contains arbitrary security token data that is tagged with ASN.1 metadata.
type SecurityBlob struct {
Data []byte `asn1:"explicit,tag:0,octet"`
}
func (*SecurityBlob) Marshal
func (s *SecurityBlob) Marshal() ([]byte, error)
Marshal encodes this SecurityBlob into ASN.1 format. The data is wrapped in a [1] ASN.1 tag before encoding.
Returns:
- []byte: The ASN.1 encoded security blob
- error: Any error encountered during marshaling
func (*SecurityBlob) Unmarshal
func (s *SecurityBlob) Unmarshal(marshalledData []byte) (int, error)
Unmarshal decodes an ASN.1 encoded security blob into this SecurityBlob struct. The data is expected to be wrapped in a [1] ASN.1 tag.
Parameters:
- marshalledData: The ASN.1 encoded bytes to unmarshal
Returns:
- int: Number of bytes read from marshalledData
- error: Any error encountered during unmarshaling
type ServerIdentity
ServerIdentity is the server identity advertised in the NTLM CHALLENGE: the NetBIOS and DNS computer/domain names from the TargetInfo AV pairs, and the operating-system version from the CHALLENGE Version field. Individual fields are empty (or zero) when the server did not advertise them.
type ServerIdentity struct {
NetBIOSComputerName string
NetBIOSDomainName string
DNSComputerName string
DNSDomainName string
OSVersionMajor uint8
OSVersionMinor uint8
OSVersionBuild uint16
}