| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- package gssapi
- import (
- "errors"
- "fmt"
- "github.com/jcmturner/asn1"
- "gopkg.in/jcmturner/gokrb5.v2/credentials"
- "gopkg.in/jcmturner/gokrb5.v2/messages"
- "gopkg.in/jcmturner/gokrb5.v2/types"
- )
- /*
- https://msdn.microsoft.com/en-us/library/ms995330.aspx
- NegotiationToken ::= CHOICE {
- negTokenInit [0] NegTokenInit, This is the Negotiation token sent from the client to the server.
- negTokenResp [1] NegTokenResp
- }
- NegTokenInit ::= SEQUENCE {
- mechTypes [0] MechTypeList,
- reqFlags [1] ContextFlags OPTIONAL,
- -- inherited from RFC 2478 for backward compatibility,
- -- RECOMMENDED to be left out
- mechToken [2] OCTET STRING OPTIONAL,
- mechListMIC [3] OCTET STRING OPTIONAL,
- ...
- }
- NegTokenResp ::= SEQUENCE {
- negState [0] ENUMERATED {
- accept-completed (0),
- accept-incomplete (1),
- reject (2),
- request-mic (3)
- } OPTIONAL,
- -- REQUIRED in the first reply from the target
- supportedMech [1] MechType OPTIONAL,
- -- present only in the first reply from the target
- responseToken [2] OCTET STRING OPTIONAL,
- mechListMIC [3] OCTET STRING OPTIONAL,
- ...
- }
- */
- // NegTokenInit implements Negotiation Token of type Init
- type NegTokenInit struct {
- MechTypes []asn1.ObjectIdentifier `asn1:"explicit,tag:0"`
- ReqFlags ContextFlags `asn1:"explicit,optional,tag:1"`
- MechToken []byte `asn1:"explicit,optional,tag:2"`
- MechTokenMIC []byte `asn1:"explicit,optional,tag:3"`
- }
- // NegTokenResp implements Negotiation Token of type Resp/Targ
- type NegTokenResp struct {
- NegState asn1.Enumerated `asn1:"explicit,tag:0"`
- SupportedMech asn1.ObjectIdentifier `asn1:"explicit,optional,tag:1"`
- ResponseToken []byte `asn1:"explicit,optional,tag:2"`
- MechListMIC []byte `asn1:"explicit,optional,tag:3"`
- }
- // NegTokenTarg implements Negotiation Token of type Resp/Targ
- type NegTokenTarg NegTokenResp
- // UnmarshalNegToken umarshals and returns either a NegTokenInit or a NegTokenResp.
- //
- // The boolean indicates if the response is a NegTokenInit.
- // If error is nil and the boolean is false the response is a NegTokenResp.
- func UnmarshalNegToken(b []byte) (bool, interface{}, error) {
- var a asn1.RawValue
- _, err := asn1.Unmarshal(b, &a)
- if err != nil {
- return false, nil, fmt.Errorf("Error unmarshalling NegotiationToken: %v", err)
- }
- switch a.Tag {
- case 0:
- var negToken NegTokenInit
- _, err = asn1.Unmarshal(a.Bytes, &negToken)
- if err != nil {
- return false, nil, fmt.Errorf("Error unmarshalling NegotiationToken type %d (Init): %v", a.Tag, err)
- }
- return true, negToken, nil
- case 1:
- var negToken NegTokenResp
- _, err = asn1.Unmarshal(a.Bytes, &negToken)
- if err != nil {
- return false, nil, fmt.Errorf("Error unmarshalling NegotiationToken type %d (Resp/Targ): %v", a.Tag, err)
- }
- return false, negToken, nil
- default:
- return false, nil, errors.New("Unknown choice type for NegotiationToken")
- }
- }
- // Marshal an Init negotiation token
- func (n *NegTokenInit) Marshal() ([]byte, error) {
- b, err := asn1.Marshal(*n)
- if err != nil {
- return nil, err
- }
- nt := asn1.RawValue{
- Tag: 0,
- Class: 2,
- IsCompound: true,
- Bytes: b,
- }
- nb, err := asn1.Marshal(nt)
- if err != nil {
- return nil, err
- }
- return nb, nil
- }
- // Marshal a Resp/Targ negotiation token
- func (n *NegTokenResp) Marshal() ([]byte, error) {
- b, err := asn1.Marshal(*n)
- if err != nil {
- return nil, err
- }
- nt := asn1.RawValue{
- Tag: 1,
- Class: 2,
- IsCompound: true,
- Bytes: b,
- }
- nb, err := asn1.Marshal(nt)
- if err != nil {
- return nil, err
- }
- return nb, nil
- }
- // NewNegTokenInitKrb5 creates new Init negotiation token for Kerberos 5
- func NewNegTokenInitKrb5(creds credentials.Credentials, tkt messages.Ticket, sessionKey types.EncryptionKey) (NegTokenInit, error) {
- mt, err := NewKRB5APREQMechToken(creds, tkt, sessionKey)
- if err != nil {
- return NegTokenInit{}, fmt.Errorf("Error getting MechToken; %v", err)
- }
- return NegTokenInit{
- MechTypes: []asn1.ObjectIdentifier{MechTypeOIDKRB5},
- MechToken: mt,
- }, nil
- }
|