Просмотр исходного кода

ASReq working against kdc server

Jonathan Turner 9 лет назад
Родитель
Сommit
ed0da60fb0

+ 18 - 1
asn1tools/tools.go

@@ -1,5 +1,6 @@
 package asn1tools
 
+
 // ASN1 Length octets.
 // There are two forms: short (for lengths between 0 and 127), and long definite (for lengths between 0 and 2^1008 -1).
 // Short form. One octet. Bit 8 has value "0" and bits 7-1 give the length.
@@ -21,6 +22,21 @@ func MarshalLengthBytes(l int) []byte {
 	return append([]byte{byte(128 + len(b))}, b...)
 }
 
+func GetLengthFromASN(b []byte) int {
+	if int(b[1]) <= 127 {
+		return int(b[1])
+	}
+	// The bytes that indicate the length
+	lb := b[2:2+int(b[1]) - 128]
+	base := 1
+	l := 0
+	for i := len(lb)-1; i >= 0; i-- {
+		l += int(lb[i]) * base
+		base = base * 256
+	}
+	return l
+}
+
 // The Marshal method of golang's asn1 package does not enable you to configure to wrap the output in an application tag.
 // This method adds that wrapping tag
 func AddASNAppTag(b []byte, tag int) []byte {
@@ -32,7 +48,8 @@ func AddASNAppTag(b []byte, tag int) []byte {
 	//| Value:      | 0                            | 1                          | 1                                         | From the RFC spec 4120        |
 	//| Explanation | Defined by the ASN1 encoding rules for an application tag | A value of 1 indicates a constructed type | The ASN Application tag value |
 	// Therefore the value of the byte is an integer = ( Application tag value + 96 )
-	b = append(MarshalLengthBytes(int(b[1])+2), b...)
+	//b = append(MarshalLengthBytes(int(b[1])+2), b...)
+	b = append(MarshalLengthBytes(len(b)), b...)
 	b = append([]byte{byte(96 + tag)}, b...)
 	return b
 }

+ 36 - 21
debug.go

@@ -1,35 +1,50 @@
 package main
 
 import (
-	"encoding/asn1"
-	"encoding/hex"
+	"net"
+	"github.com/jcmturner/gokrb5/messages"
+	"time"
 	"fmt"
-	cpasn1 "github.com/jcmturner/asn1/identicalsrc"
 	"os"
 )
 
-type BitStringStruct struct {
-	Bs cpasn1.BitString `asn1:"explicit,tag:0"`
-}
-
 func main() {
-	var o BitStringStruct
-	bs, _ := hex.DecodeString("3009a007030500fedcba90")
-	_, e := asn1.Unmarshal(bs, &o)
-	if e != nil {
-		fmt.Fprintf(os.Stderr, "Error: %v\n", e)
-	} else {
-		fmt.Fprintf(os.Stderr, "Bitstring: %+v\n", o)
-	}
-	n, err := asn1.Marshal(o)
+	udpAddr, _ := net.ResolveUDPAddr("udp", "10.80.88.88:88")
+	realm := "TEST.GOKRB5"
+
+	conn, _ := net.DialUDP("udp", nil, udpAddr)
+	defer conn.Close()
+
+	a := messages.NewASReq()
+	a.ReqBody.Realm = realm
+	a.ReqBody.CName.NameString = []string{"testuser1"}
+	a.ReqBody.SName.NameType = 2
+	a.ReqBody.SName.NameString = []string{"krbtgt", realm}
+	a.ReqBody.Till = time.Now().Add(10 * time.Hour)
+	a.ReqBody.Nonce = 2069991465
+	a.ReqBody.EType = []int{18}
+	fmt.Fprintf(os.Stdout, "AS_REQ: %+v\n", a)
+	b, err := a.Marshal()
 	if err != nil {
-		fmt.Fprintf(os.Stderr, "Error: %v\n", e)
+		fmt.Fprintf(os.Stderr, "Error marshalling AS_REQ: %v\n", err)
 	}
-	c, err := cpasn1.Marshal(o)
+	var m messages.ASReq
+	m.Unmarshal(b)
+	b, err = m.Marshal()
 	if err != nil {
-		fmt.Fprintf(os.Stderr, "Error: %v\n", e)
+		fmt.Fprintf(os.Stderr, "Error marshalling AS_REQ: %v\n", err)
 	}
-	fmt.Fprintf(os.Stderr, "Input bytes:         %v\nOutput originalasn1: %v\n", bs, n)
-	fmt.Fprintf(os.Stderr, "Output copy of asn1: %v\n", c)
+	fmt.Fprintf(os.Stdout, "AS_REQ post marshal: %+v\n", m)
+	_, _ = conn.Write(b)
+
+
+	buf := make([]byte, 4096)
+	n,_,err := conn.ReadFrom(buf)
+
+	var r messages.ASRep
+	r.Unmarshal(buf[:n])
+	fmt.Fprintf(os.Stdout, "AS REP: %+v\n", r)
+
+
 
 }

+ 1 - 1
messages/APRep.go

@@ -30,7 +30,7 @@ type APRep struct {
 }
 
 type EncAPRepPart struct {
-	CTime          time.Time           `asn1:"explicit,tag:0"`
+	CTime          time.Time           `asn1:"generalized,explicit,tag:0"`
 	Cusec          int                 `asn1:"explicit,tag:1"`
 	Subkey         types.EncryptionKey `asn1:"optional,explicit,tag:2"`
 	SequenceNumber int                 `asn1:"optional,explicit,tag:3"`

+ 6 - 6
messages/KDCRep.go

@@ -44,12 +44,12 @@ type EncKDCRepPart struct {
 	Key           types.EncryptionKey `asn1:"explicit,tag:0"`
 	LastReqs      []LastReq           `asn1:"explicit,tag:1"`
 	Nonce         int                 `asn1:"explicit,tag:2"`
-	KeyExpiration time.Time           `asn1:"explicit,optional,tag:3"`
+	KeyExpiration time.Time           `asn1:"generalized,explicit,optional,tag:3"`
 	Flags         asn1.BitString      `asn1:"explicit,tag:4"`
-	AuthTime      time.Time           `asn1:"explicit,tag:5"`
-	StartTime     time.Time           `asn1:"explicit,optional,tag:6"`
-	EndTime       time.Time           `asn1:"explicit,tag:7"`
-	RenewTill     time.Time           `asn1:"explicit,optional,tag:8"`
+	AuthTime      time.Time           `asn1:"generalized,explicit,tag:5"`
+	StartTime     time.Time           `asn1:"generalized,explicit,optional,tag:6"`
+	EndTime       time.Time           `asn1:"generalized,explicit,tag:7"`
+	RenewTill     time.Time           `asn1:"generalized,explicit,optional,tag:8"`
 	SRealm        string              `asn1:"generalstring,explicit,tag:9"`
 	SName         types.PrincipalName `asn1:"explicit,tag:10"`
 	CAddr         []types.HostAddress `asn1:"explicit,optional,tag:11"`
@@ -57,7 +57,7 @@ type EncKDCRepPart struct {
 
 type LastReq struct {
 	LRType  int       `asn1:"explicit,tag:0"`
-	LRValue time.Time `asn1:"explicit,tag:1"`
+	LRValue time.Time `asn1:"generalized,explicit,tag:1"`
 }
 
 func (k *ASRep) Unmarshal(b []byte) error {

+ 54 - 17
messages/KDCReq.go

@@ -10,6 +10,7 @@ import (
 	"github.com/jcmturner/gokrb5/types"
 	"github.com/jcmturner/gokrb5/types/asnAppTag"
 	"time"
+	"encoding/hex"
 )
 
 type marshalKDCReq struct {
@@ -34,9 +35,9 @@ type marshalKDCReqBody struct {
 	CName       types.PrincipalName `asn1:"explicit,optional,tag:1"`
 	Realm       string              `asn1:"generalstring,explicit,tag:2"`
 	SName       types.PrincipalName `asn1:"explicit,optional,tag:3"`
-	From        time.Time           `asn1:"explicit,optional,tag:4"`
-	Till        time.Time           `asn1:"explicit,tag:5"`
-	RTime       time.Time           `asn1:"explicit,optional,tag:6"`
+	From        time.Time           `asn1:"generalized,explicit,optional,tag:4"`
+	Till        time.Time           `asn1:"generalized,explicit,tag:5"`
+	RTime       time.Time           `asn1:"generalized,explicit,optional,tag:6"`
 	Nonce       int                 `asn1:"explicit,tag:7"`
 	EType       []int               `asn1:"explicit,tag:8"`
 	Addresses   []types.HostAddress `asn1:"explicit,optional,tag:9"`
@@ -50,9 +51,9 @@ type KDCReqBody struct {
 	CName             types.PrincipalName `asn1:"explicit,optional,tag:1"`
 	Realm             string              `asn1:"generalstring,explicit,tag:2"`
 	SName             types.PrincipalName `asn1:"explicit,optional,tag:3"`
-	From              time.Time           `asn1:"explicit,optional,tag:4"`
-	Till              time.Time           `asn1:"explicit,tag:5"`
-	RTime             time.Time           `asn1:"explicit,optional,tag:6"`
+	From              time.Time           `asn1:"generalized,explicit,optional,tag:4"`
+	Till              time.Time           `asn1:"generalized,explicit,tag:5"`
+	RTime             time.Time           `asn1:"generalized,explicit,optional,tag:6"`
 	Nonce             int                 `asn1:"explicit,tag:7"`
 	EType             []int               `asn1:"explicit,tag:8"`
 	Addresses         []types.HostAddress `asn1:"explicit,optional,tag:9"`
@@ -60,6 +61,23 @@ type KDCReqBody struct {
 	AdditionalTickets []types.Ticket      `asn1:"explicit,optional,tag:11"`
 }
 
+func NewASReq() ASReq {
+	opts := asn1.BitString{}
+	opts.Bytes, _ = hex.DecodeString("40000010")
+	opts.BitLength = len(opts.Bytes) * 8
+	pn := types.PrincipalName{NameType: 1}
+
+	return ASReq{
+		PVNO:    5,
+		MsgType: types.KrbDictionary.MsgTypesByName["KRB_AS_REQ"],
+		ReqBody: KDCReqBody{
+			KDCOptions: opts,
+			CName: pn,
+			SName: pn,
+		},
+	}
+}
+
 func (k *ASReq) Unmarshal(b []byte) error {
 	var m marshalKDCReq
 	_, err := asn1.UnmarshalWithParams(b, &m, fmt.Sprintf("application,explicit,tag:%v", asnAppTag.ASREQ))
@@ -135,16 +153,6 @@ func (k *KDCReqBody) Unmarshal(b []byte) error {
 	return nil
 }
 
-//func NewASReq() ASReq {
-//	return ASReq{
-//		PVNO:    5,
-//		MsgType: types.KrbDictionary.MsgTypesByName["KRB_AS_REQ"],
-//		ReqBody: KDCReqBody{
-//			KDCOptions: asn1.BitString{},
-//		},
-//	}
-//}
-
 func (k *ASReq) Marshal() ([]byte, error) {
 	m := marshalKDCReq{
 		PVNO:    k.PVNO,
@@ -170,6 +178,31 @@ func (k *ASReq) Marshal() ([]byte, error) {
 	return mk, nil
 }
 
+func (k *TGSReq) Marshal() ([]byte, error) {
+	m := marshalKDCReq{
+		PVNO:    k.PVNO,
+		MsgType: k.MsgType,
+		PAData:  k.PAData,
+	}
+	b, err := k.ReqBody.Marshal()
+	if err != nil {
+		var mk []byte
+		return mk, err
+	}
+	m.ReqBody = asn1.RawValue{
+		Class:      2,
+		IsCompound: true,
+		Tag:        4,
+		Bytes:      b,
+	}
+	mk, err := asn1.Marshal(m)
+	if err != nil {
+		return mk, fmt.Errorf("Error marshalling AS_REQ: %v", err)
+	}
+	mk = asn1tools.AddASNAppTag(mk, asnAppTag.TGSREQ)
+	return mk, nil
+}
+
 func (k *KDCReqBody) Marshal() ([]byte, error) {
 	var b []byte
 	m := marshalKDCReqBody{
@@ -186,9 +219,13 @@ func (k *KDCReqBody) Marshal() ([]byte, error) {
 		EncAuthData: k.EncAuthData,
 	}
 	rawtkts, err := types.MarshalTicketSequence(k.AdditionalTickets)
+	//The asn1.rawValue needs the tag setting on it for where it is in the KDCReqBody
+	rawtkts.Tag = 11
 	if err != nil {
 		return b, fmt.Errorf("Error in marshalling KDC request body additional tickets: %v", err)
 	}
-	m.AdditionalTickets = rawtkts
+	if len(rawtkts.Bytes) > 0 {
+		m.AdditionalTickets = rawtkts
+	}
 	return asn1.Marshal(m)
 }

+ 19 - 12
messages/KDCReq_test.go

@@ -414,12 +414,7 @@ func TestMarshalKDCReqBody(t *testing.T) {
 	if err != nil {
 		t.Fatalf("Unmarshal error of %s: %v\n", v, err)
 	}
-	var ma KDCReqBody
-	err = ma.Unmarshal(mb)
-	if err != nil {
-		t.Fatalf("Unmarshal of marshalled output failed: %v", err)
-	}
-	assert.Equal(t, a, ma, "Marshalling of KDCReqBody not as expected")
+	assert.Equal(t, b, mb, "Marshal bytes of KDCReqBody not as expected")
 }
 
 func TestMarshalASReq(t *testing.T) {
@@ -433,15 +428,27 @@ func TestMarshalASReq(t *testing.T) {
 	if err != nil {
 		t.Fatalf("Unmarshal error of %s: %v\n", v, err)
 	}
-	// Marshal and re-unmarshal the result nd then compare
 	mb, err := a.Marshal()
 	if err != nil {
 		t.Fatalf("Marshal of ticket errored: %v", err)
 	}
-	var ma ASReq
-	err = ma.Unmarshal(mb)
+	assert.Equal(t, b, mb, "Marshal bytes of ASReq not as expected")
+}
+
+func TestMarshalTGSReq(t *testing.T) {
+	var a TGSReq
+	v := "encode_krb5_tgs_req"
+	b, err := hex.DecodeString(testdata.TestVectors[v])
+	if err != nil {
+		t.Fatalf("Test vector read error of %s: %v\n", v, err)
+	}
+	err = a.Unmarshal(b)
 	if err != nil {
-		t.Fatalf("Unmarshal of marshalled output failed: %v", err)
+		t.Fatalf("Unmarshal error of %s: %v\n", v, err)
 	}
-	assert.Equal(t, a, ma, "Marshalling of ASReq not as expected")
-}
+	mb, err := a.Marshal()
+	if err != nil {
+		t.Fatalf("Marshal of ticket errored: %v", err)
+	}
+	assert.Equal(t, b, mb, "Marshal bytes of TGSReq not as expected")
+}

+ 5 - 5
messages/KRBCred.go

@@ -29,7 +29,7 @@ type KRBCred struct {
 type EncKrbCredPart struct {
 	TicketInfo []KrbCredInfo     `asn1:"explicit,tag:0"`
 	Nouce      int               `asn1:"optional,explicit,tag:1"`
-	Timestamp  time.Time         `asn1:"optional,explicit,tag:2"`
+	Timestamp  time.Time         `asn1:"generalized,optional,explicit,tag:2"`
 	Usec       int               `asn1:"optional,explicit,tag:3"`
 	SAddress   types.HostAddress `asn1:"optional,explicit,tag:4"`
 	RAddress   types.HostAddress `asn1:"optional,explicit,tag:5"`
@@ -40,10 +40,10 @@ type KrbCredInfo struct {
 	PRealm    string              `asn1:"generalstring,optional,explicit,tag:1"`
 	PName     types.PrincipalName `asn1:"optional,explicit,tag:2"`
 	Flags     asn1.BitString      `asn1:"optional,explicit,tag:3"`
-	AuthTime  time.Time           `asn1:"optional,explicit,tag:4"`
-	StartTime time.Time           `asn1:"optional,explicit,tag:5"`
-	EndTime   time.Time           `asn1:"optional,explicit,tag:6"`
-	RenewTill time.Time           `asn1:"optional,explicit,tag:7"`
+	AuthTime  time.Time           `asn1:"generalized,optional,explicit,tag:4"`
+	StartTime time.Time           `asn1:"generalized,optional,explicit,tag:5"`
+	EndTime   time.Time           `asn1:"generalized,optional,explicit,tag:6"`
+	RenewTill time.Time           `asn1:"generalized,optional,explicit,tag:7"`
 	SRealm    string              `asn1:"optional,explicit,ia5,tag:8"`
 	SName     types.PrincipalName `asn1:"optional,explicit,tag:9"`
 	CAddr     types.HostAddresses `asn1:"optional,explicit,tag:10"`

+ 2 - 2
messages/KRBError.go

@@ -11,9 +11,9 @@ import (
 type KRBError struct {
 	PVNO      int                 `asn1:"explicit,tag:0"`
 	MsgType   int                 `asn1:"explicit,tag:1"`
-	CTime     time.Time           `asn1:"optional,explicit,tag:2"`
+	CTime     time.Time           `asn1:"generalized,optional,explicit,tag:2"`
 	Cusec     int                 `asn1:"optional,explicit,tag:3"`
-	STime     time.Time           `asn1:"explicit,tag:4"`
+	STime     time.Time           `asn1:"generalized,explicit,tag:4"`
 	Susec     int                 `asn1:"explicit,tag:5"`
 	ErrorCode int                 `asn1:"explicit,tag:6"`
 	CRealm    string              `asn1:"generalstring,optional,explicit,tag:7"`

+ 1 - 1
messages/KRBPriv.go

@@ -16,7 +16,7 @@ type KRBPriv struct {
 
 type EncKrbPrivPart struct {
 	UserData       []byte            `asn1:"explicit,tag:0"`
-	Timestamp      time.Time         `asn1:"optional,explicit,tag:1"`
+	Timestamp      time.Time         `asn1:"generalized,optional,explicit,tag:1"`
 	Usec           int               `asn1:"optional,explicit,tag:2"`
 	SequenceNumber int               `asn1:"optional,explicit,tag:3"`
 	SAddress       types.HostAddress `asn1:"explicit,tag:4"`

+ 1 - 1
messages/KRBSafe.go

@@ -35,7 +35,7 @@ type KRBSafe struct {
 
 type KRBSafeBody struct {
 	UserData       []byte            `asn1:"explicit,tag:0"`
-	Timestamp      time.Time         `asn1:"optional,explicit,tag:1"`
+	Timestamp      time.Time         `asn1:"generalized,optional,explicit,tag:1"`
 	Usec           int               `asn1:"optional,explicit,tag:2"`
 	SequenceNumber int               `asn1:"optional,explicit,tag:3"`
 	SAddress       types.HostAddress `asn1:"explicit,tag:4"`

+ 1 - 1
types/Authenticator.go

@@ -33,7 +33,7 @@ type Authenticator struct {
 	CName             PrincipalName     `asn1:"explicit,tag:2"`
 	Cksum             Checksum          `asn1:"explicit,optional,tag:3"`
 	Cusec             int               `asn1:"explicit,tag:4"`
-	CTime             time.Time         `asn1:"explicit,tag:5"`
+	CTime             time.Time         `asn1:"generalized,explicit,tag:5"`
 	SubKey            EncryptionKey     `asn1:"explicit,optional,tag:6"`
 	SeqNumber         int               `asn1:"explicit,optional,tag:7"`
 	AuthorizationData AuthorizationData `asn1:"explicit,optional,tag:8"`

+ 1 - 1
types/PAData.go

@@ -19,7 +19,7 @@ type MethodData []PAData
 type PAEncTimestamp EncryptedData
 
 type PAEncTSEnc struct {
-	PATimestamp time.Time `asn1:"explicit,tag:0"`
+	PATimestamp time.Time `asn1:"generalized,explicit,tag:0"`
 	PAUSec      int       `asn1:"explicit,optional,tag:1"`
 }
 

+ 8 - 5
types/Ticket.go

@@ -24,10 +24,10 @@ type EncTicketPart struct {
 	CRealm            string            `asn1:"generalstring,explicit,tag:2"`
 	CName             PrincipalName     `asn1:"explicit,tag:3"`
 	Transited         TransitedEncoding `asn1:"explicit,tag:4"`
-	AuthTime          time.Time         `asn1:"explicit,tag:5"`
-	StartTime         time.Time         `asn1:"explicit,optional,tag:6"`
-	EndTime           time.Time         `asn1:"explicit,tag:7"`
-	RenewTill         time.Time         `asn1:"explicit,optional,tag:8"`
+	AuthTime          time.Time         `asn1:"generalized,explicit,tag:5"`
+	StartTime         time.Time         `asn1:"generalized,explicit,optional,tag:6"`
+	EndTime           time.Time         `asn1:"generalized,explicit,tag:7"`
+	RenewTill         time.Time         `asn1:"generalized,explicit,optional,tag:8"`
 	CAddr             HostAddresses     `asn1:"explicit,optional,tag:9"`
 	AuthorizationData AuthorizationData `asn1:"explicit,optional,tag:10"`
 }
@@ -89,7 +89,10 @@ func MarshalTicketSequence(tkts []Ticket) (asn1.RawValue, error) {
 	raw := asn1.RawValue{
 		Class:      2,
 		IsCompound: true,
-		//Tag: 11,
+	}
+	if len(tkts) < 1 {
+		// There are no tickets to marshal
+		return raw, nil
 	}
 	var btkts []byte
 	for i, t := range tkts {