Jonathan Turner преди 8 години
родител
ревизия
7b914ca9f0
променени са 6 файла, в които са добавени 58 реда и са изтрити 23 реда
  1. 5 2
      client/ASExchange.go
  2. 12 4
      gssapi/krb5Token.go
  3. 4 1
      gssapi/krb5Token_test.go
  4. 19 9
      messages/KDCReq.go
  5. 1 1
      service/APExchange_test.go
  6. 17 6
      types/Authenticator.go

+ 5 - 2
client/ASExchange.go

@@ -17,8 +17,11 @@ func (cl *Client) ASExchange() error {
 	if !cl.IsConfigured() {
 		return errors.New("Client is not configured correctly")
 	}
-	ASReq := messages.NewASReq(cl.Config, cl.Credentials.CName)
-	err := setPAData(cl, messages.KRBError{}, &ASReq)
+	ASReq, err := messages.NewASReq(cl.Config, cl.Credentials.CName)
+	if err != nil {
+		return krberror.Errorf(err, krberror.KRBMSG_ERROR, "Error generating new AS_REQ")
+	}
+	err = setPAData(cl, messages.KRBError{}, &ASReq)
 	if err != nil {
 		return krberror.Errorf(err, krberror.KRBMSG_ERROR, "AS Exchange Error: failed setting AS_REQ PAData")
 	}

+ 12 - 4
gssapi/krb5Token.go

@@ -9,6 +9,7 @@ import (
 	"github.com/jcmturner/gokrb5/credentials"
 	"github.com/jcmturner/gokrb5/crypto"
 	"github.com/jcmturner/gokrb5/iana/chksumtype"
+	"github.com/jcmturner/gokrb5/krberror"
 	"github.com/jcmturner/gokrb5/messages"
 	"github.com/jcmturner/gokrb5/types"
 )
@@ -101,10 +102,14 @@ func NewKRB5APREQMechToken(creds credentials.Credentials, tkt messages.Ticket, s
 	tb, _ := hex.DecodeString(TOK_ID_KRB_AP_REQ)
 	b = append(b, tb...)
 	// Add the token
+	auth, err := newAuthenticator(creds, sessionKey.KeyType)
+	if err != nil {
+		return []byte{}, err
+	}
 	APReq, err := messages.NewAPReq(
 		tkt,
 		sessionKey,
-		newAuthenticator(creds, sessionKey.KeyType),
+		auth,
 	)
 	tb, err = APReq.Marshal()
 	if err != nil {
@@ -115,16 +120,19 @@ func NewKRB5APREQMechToken(creds credentials.Credentials, tkt messages.Ticket, s
 }
 
 // Create new kerberos authenticator for kerberos MechToken
-func newAuthenticator(creds credentials.Credentials, keyType int) types.Authenticator {
+func newAuthenticator(creds credentials.Credentials, keyType int) (types.Authenticator, error) {
 	//RFC 4121 Section 4.1.1
-	auth := types.NewAuthenticator(creds.Realm, creds.CName)
+	auth, err := types.NewAuthenticator(creds.Realm, creds.CName)
+	if err != nil {
+		return auth, krberror.Errorf(err, krberror.KRBMSG_ERROR, "Error generating new authenticator")
+	}
 	etype, _ := crypto.GetEtype(keyType)
 	auth.GenerateSeqNumberAndSubKey(keyType, etype.GetKeyByteSize())
 	auth.Cksum = types.Checksum{
 		CksumType: chksumtype.GSSAPI,
 		Checksum:  newAuthenticatorChksum([]int{GSS_C_INTEG_FLAG, GSS_C_CONF_FLAG}),
 	}
-	return auth
+	return auth, nil
 }
 
 // Create new authenticator checksum for kerberos MechToken

+ 4 - 1
gssapi/krb5Token_test.go

@@ -47,7 +47,10 @@ func TestMechToken_newAuthenticator(t *testing.T) {
 	creds := credentials.NewCredentials("hftsai", testdata.TEST_REALM)
 	creds.CName.NameString = testdata.TEST_PRINCIPALNAME_NAMESTRING
 	etypeID := 18
-	a := newAuthenticator(creds, etypeID)
+	a, err := newAuthenticator(creds, etypeID)
+	if err != nil {
+		t.Fatalf("Error creating authenticator: %v", err)
+	}
 	assert.Equal(t, 32771, a.Cksum.CksumType, "Checksum type in authenticator for SPNEGO mechtoken not as expected.")
 	assert.Equal(t, 18, a.SubKey.KeyType, "Subkey not of the expected type.")
 	assert.Equal(t, 32, len(a.SubKey.KeyValue), "Subkey value not of the right length")

+ 19 - 9
messages/KDCReq.go

@@ -4,6 +4,7 @@ package messages
 // Section: 5.4.1
 
 import (
+	"crypto/rand"
 	"fmt"
 	"github.com/jcmturner/asn1"
 	"github.com/jcmturner/gokrb5/asn1tools"
@@ -18,7 +19,8 @@ import (
 	"github.com/jcmturner/gokrb5/iana/patype"
 	"github.com/jcmturner/gokrb5/krberror"
 	"github.com/jcmturner/gokrb5/types"
-	"math/rand"
+	"math"
+	"math/big"
 	"time"
 )
 
@@ -81,10 +83,12 @@ type KDCReqBody struct {
 }
 
 // NewASReq generates a new KRB_AS_REQ struct.
-func NewASReq(c *config.Config, cname types.PrincipalName) ASReq {
-	nonce := int(rand.Int31())
+func NewASReq(c *config.Config, cname types.PrincipalName) (ASReq, error) {
+	nonce, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt32))
+	if err != nil {
+		return ASReq{}, err
+	}
 	t := time.Now().UTC()
-
 	a := ASReq{
 		KDCReqFields{
 			PVNO:    iana.PVNO,
@@ -100,7 +104,7 @@ func NewASReq(c *config.Config, cname types.PrincipalName) ASReq {
 				},
 				Till: t.Add(c.LibDefaults.Ticket_lifetime),
 				//Till:  t.Add(time.Duration(24) * time.Hour),
-				Nonce: nonce,
+				Nonce: int(nonce.Int64()),
 				EType: c.LibDefaults.Default_tkt_enctype_ids,
 			},
 		},
@@ -120,12 +124,15 @@ func NewASReq(c *config.Config, cname types.PrincipalName) ASReq {
 		a.ReqBody.RTime = t.Add(time.Duration(48) * time.Hour)
 
 	}
-	return a
+	return a, nil
 }
 
 // NewTGSReq generates a new KRB_TGS_REQ struct.
 func NewTGSReq(cname types.PrincipalName, c *config.Config, tkt Ticket, sessionKey types.EncryptionKey, spn types.PrincipalName, renewal bool) (TGSReq, error) {
-	nonce := int(rand.Int31())
+	nonce, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt32))
+	if err != nil {
+		return TGSReq{}, err
+	}
 	t := time.Now().UTC()
 	a := TGSReq{
 		KDCReqFields{
@@ -137,7 +144,7 @@ func NewTGSReq(cname types.PrincipalName, c *config.Config, tkt Ticket, sessionK
 				SName:      spn,
 				Till:       t.Add(c.LibDefaults.Ticket_lifetime),
 				//Till:  t.Add(time.Duration(2) * time.Minute),
-				Nonce: nonce,
+				Nonce: int(nonce.Int64()),
 				EType: c.LibDefaults.Default_tgs_enctype_ids,
 			},
 			Renewal: renewal,
@@ -160,7 +167,10 @@ func NewTGSReq(cname types.PrincipalName, c *config.Config, tkt Ticket, sessionK
 		types.SetFlag(&a.ReqBody.KDCOptions, flags.Renew)
 		types.SetFlag(&a.ReqBody.KDCOptions, flags.Renewable)
 	}
-	auth := types.NewAuthenticator(c.LibDefaults.Default_realm, cname)
+	auth, err := types.NewAuthenticator(c.LibDefaults.Default_realm, cname)
+	if err != nil {
+		return a, krberror.Errorf(err, krberror.KRBMSG_ERROR, "Error generating new authenticator")
+	}
 	// Add the CName to make validation of the reply easier
 	a.ReqBody.CName = auth.CName
 	b, err := a.ReqBody.Marshal()

+ 1 - 1
service/APExchange_test.go

@@ -327,7 +327,7 @@ func TestValidateAPREQ_ExpiredTicket(t *testing.T) {
 }
 
 func newTestAuthenticator(creds credentials.Credentials) types.Authenticator {
-	auth := types.NewAuthenticator(creds.Realm, creds.CName)
+	auth, _ := types.NewAuthenticator(creds.Realm, creds.CName)
 	auth.GenerateSeqNumberAndSubKey(18, 32)
 	//auth.Cksum = types.Checksum{
 	//	CksumType: chksumtype.GSSAPI,

+ 17 - 6
types/Authenticator.go

@@ -2,12 +2,14 @@
 package types
 
 import (
+	"crypto/rand"
 	"fmt"
 	"github.com/jcmturner/asn1"
 	"github.com/jcmturner/gokrb5/asn1tools"
 	"github.com/jcmturner/gokrb5/iana"
 	"github.com/jcmturner/gokrb5/iana/asnAppTag"
-	"math/rand"
+	"math"
+	"math/big"
 	"time"
 )
 
@@ -46,7 +48,11 @@ type Authenticator struct {
 }
 
 // NewAuthenticator creates a new Authenticator.
-func NewAuthenticator(realm string, cname PrincipalName) Authenticator {
+func NewAuthenticator(realm string, cname PrincipalName) (Authenticator, error) {
+	seq, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt32))
+	if err != nil {
+		return Authenticator{}, err
+	}
 	t := time.Now().UTC()
 	return Authenticator{
 		AVNO:      iana.PVNO,
@@ -55,13 +61,17 @@ func NewAuthenticator(realm string, cname PrincipalName) Authenticator {
 		Cksum:     Checksum{},
 		Cusec:     int((t.UnixNano() / int64(time.Microsecond)) - (t.Unix() * 1e6)),
 		CTime:     t,
-		SeqNumber: int(rand.Int31()),
-	}
+		SeqNumber: int(seq.Int64()),
+	}, nil
 }
 
 // GenerateSeqNumberAndSubKey sets the Authenticator's sequence number and subkey.
-func (a *Authenticator) GenerateSeqNumberAndSubKey(keyType, keySize int) {
-	a.SeqNumber = int(rand.Int31())
+func (a *Authenticator) GenerateSeqNumberAndSubKey(keyType, keySize int) error {
+	seq, err := rand.Int(rand.Reader, big.NewInt(math.MaxUint32))
+	if err != nil {
+		return err
+	}
+	a.SeqNumber = int(seq.Int64())
 	//Generate subkey value
 	sk := make([]byte, keySize, keySize)
 	rand.Read(sk)
@@ -69,6 +79,7 @@ func (a *Authenticator) GenerateSeqNumberAndSubKey(keyType, keySize int) {
 		KeyType:  keyType,
 		KeyValue: sk,
 	}
+	return nil
 }
 
 // Unmarshal bytes into the Authenticator.