ソースを参照

PA-ENC-TS-ENC and PA-PW-SALT

Jonathan Turner 9 年 前
コミット
1f41243021
5 ファイル変更111 行追加21 行削除
  1. 34 16
      crypto/EncryptionEngine.go
  2. 6 5
      debug.go
  3. 48 0
      messages/KDCRep_test.go
  4. 10 0
      types/Cryptosystem.go
  5. 13 0
      types/PAData.go

+ 34 - 16
crypto/EncryptionEngine.go

@@ -9,6 +9,7 @@ import (
 	"github.com/jcmturner/gokrb5/types"
 	"hash"
 	"encoding/hex"
+	"github.com/jcmturner/gokrb5/keytab"
 )
 
 type EType interface {
@@ -153,35 +154,38 @@ func DecryptEncPart(key []byte, pe types.EncryptedData, etype EType, usage uint3
 
 func GetKeyFromPassword(passwd string, cn types.PrincipalName, realm string, etypeId int, pas types.PADataSequence) ([]byte, EType, error) {
 	var key []byte
-	var etype EType
+	etype, err := GetEtype(etypeId)
+	if err != nil {
+		return key, etype, fmt.Errorf("Error getting encryption type: %v", err)
+	}
+	sk2p := etype.GetDefaultStringToKeyParams()
+	var salt string
 	for _, pa := range pas {
-		if pa.PADataType == 19 {
+		switch pa.PADataType{
+		case 3:
+			salt = string(pa.PADataValue)
+		case 19:
 			var et2 types.ETypeInfo2
 			err := et2.Unmarshal(pa.PADataValue)
 			if err != nil {
 				return key, etype, fmt.Errorf("Error unmashalling PA Data to PA-ETYPE-INFO2: %v", err)
 			}
-			etype, err := GetEtype(et2[0].EType)
-			if err != nil {
-				return key, etype, fmt.Errorf("Error getting encryption type: %v", err)
+			if etypeId != et2[0].EType {
+				etype, err = GetEtype(et2[0].EType)
+				if err != nil {
+					return key, etype, fmt.Errorf("Error getting encryption type: %v", err)
+				}
 			}
-			sk2p := etype.GetDefaultStringToKeyParams()
 			if len(et2[0].S2KParams) == 8 {
 				sk2p = hex.EncodeToString(et2[0].S2KParams)
 			}
-			key, err := etype.StringToKey(passwd, et2[0].Salt, sk2p)
-			if err != nil {
-				return key, etype, fmt.Errorf("Error deriving key from string: %+v", err)
-			}
-			return key, etype, nil
+			salt = et2[0].Salt
 		}
 	}
-	etype, err := GetEtype(etypeId)
-	if err != nil {
-		return key, etype, fmt.Errorf("Error getting encryption type: %v", err)
+	if salt == "" {
+		salt = cn.GetSalt(realm)
 	}
-	sk2p := etype.GetDefaultStringToKeyParams()
-	key, err = etype.StringToKey(passwd, cn.GetSalt(realm), sk2p)
+	key, err = etype.StringToKey(passwd, salt, sk2p)
 	if err != nil {
 		return key, etype, fmt.Errorf("Error deriving key from string: %+v", err)
 	}
@@ -247,3 +251,17 @@ func getUsage(un uint32, o byte) []byte {
 	binary.Write(&buf, binary.BigEndian, un)
 	return append(buf.Bytes(), o)
 }
+
+func GetEncryptedData(b []byte, etype EType, crealm, username string, kt keytab.Keytab, kvno int) ([]byte, error) {
+	key, err := kt.GetKey(username, crealm, kvno, etype.GetETypeID())
+	_, cb, err := etype.Encrypt(key, b)
+	if err != nil {
+		return b, fmt.Errorf("Error encrypting data to form EncryptedData: %v", err)
+	}
+	ed := types.EncryptedData{
+		KVNO: kvno,
+		EType: etype.GetETypeID(),
+		Cipher: cb,
+	}
+	return ed.Marshal()
+}

+ 6 - 5
debug.go

@@ -59,15 +59,16 @@ func main() {
 	fmt.Fprintf(os.Stdout, "KT: %+v", kt)
 	err = r.DecryptEncPartWithKeytab(kt)
 	if err != nil {
-		fmt.Fprintf(os.Stderr, "Decrypt err: %v\n", err)
+		fmt.Fprintf(os.Stderr, "\nDecrypt err: %v\n", err)
+	} else {
+		fmt.Fprintf(os.Stdout, "\n\nAS REP decrypted with keytab: %+v\n", r)
 	}
-	fmt.Fprintf(os.Stdout, "\n\nAS REP decrypted with keytab: %+v\n", r)
 
 	pswd := "passwordvalue"
 	err = p.DecryptEncPartWithPassword(pswd)
 	if err != nil {
-		fmt.Fprintf(os.Stderr, "Decrypt err: %v\n", err)
+		fmt.Fprintf(os.Stderr, "\nDecrypt err: %v\n", err)
+	} else {
+		fmt.Fprintf(os.Stdout, "\nAS REP decrypted with passwd: %+v\n", p)
 	}
-	fmt.Fprintf(os.Stdout, "\nAS REP decrypted with passwd: %+v\n", p)
-
 }

+ 48 - 0
messages/KDCRep_test.go

@@ -16,6 +16,7 @@ const (
 	testuser1_etype18_ASREP  = "6b8202f3308202efa003020105a10302010ba22e302c302aa103020113a2230421301f301da003020112a1161b14544553542e474f4b524235746573747573657231a30d1b0b544553542e474f4b524235a4163014a003020101a10d300b1b09746573747573657231a582015a6182015630820152a003020105a10d1b0b544553542e474f4b524235a220301ea003020102a11730151b066b72627467741b0b544553542e474f4b524235a382011830820114a003020112a103020101a28201060482010237e486e32cd18ab1ac9f8d42e93f8babd7b3497084cc5599f18ec61961c6d5242d350354d99d67a7604c451116188d16cb719e84377212eac2743440e8c504ef69c755e489cc6b65f935dd032bfc076f9b2c56d816197845b8fe857d738bc59712787631a50e86833d1b0e4732c8712c856417a6a257758e7d01d3182adb3233f0dde65d228c240ed26aa1af69f8d765dc0bc69096fdb037a75af220fea176839528d44b70f7dabfaa2ea506de1296f847176a60c501fd8cef8e0a51399bb6d5f753962d96292e93ffe344c6630db912931d46d88c0279f00719e22d0efcfd4ee33a702d0b660c1f13970a9beec12c0c8af3dda68bd81ac1fe3f126d2a24ebb445c5a682012c30820128a003020112a282011f0482011bb149cc16018072c4c18788d95a33aba540e52c11b54a93e67e788d05de75d8f3d4aa1afafbbfa6fde3eb40e5aa1890644cea2607efd5213a3fd00345b02eeb9ae1b589f36c74c689cd4ec1239dfe61e42ba6afa33f6240e3cfab291e4abb465d273302dbf7dbd148a299a9369044dd03377c1687e7dd36aa66501284a4ca50c0a7b08f4f87aecfa23b0dd0b11490e3ad330906dab715de81fc52f120d09c39990b8b5330d4601cc396b2ed258834329c4cc02c563a12de3ef9bf11e946258bc2ab5257f4caa4d443a7daf0fc25f6f531c2fcba88af8ca55c85300997cd05abbea52811fe2d038ba8f62fc8e3bc71ce04362d356ea2e1df8ac55c784c53cfb07817d48e39fe99fc8788040d98209c79dcf044d97e80de9f47824646"
 	test_realm               = "TEST.GOKRB5"
 	test_user                = "testuser1"
+	test_user_password	= "passwordvalue"
 )
 
 func TestUnmarshalASRep(t *testing.T) {
@@ -271,6 +272,53 @@ func TestUnmarshalASRepDecodeAndDecrypt(t *testing.T) {
 	t.Logf("Decypted Ticket EncPart %+v", s)*/
 }
 
+func TestUnmarshalASRepDecodeAndDecrypt_withPassword(t *testing.T) {
+	var asRep ASRep
+	b, _ := hex.DecodeString(testuser1_etype18_ASREP)
+	err := asRep.Unmarshal(b)
+	if err != nil {
+		t.Fatalf("AS REP Unmarshal error: %v\n", err)
+	}
+	assert.Equal(t, 5, asRep.PVNO, "PVNO not as expected")
+	assert.Equal(t, 11, asRep.MsgType, "MsgType not as expected")
+	assert.Equal(t, test_realm, asRep.CRealm, "Client Realm not as expected")
+	assert.Equal(t, 1, asRep.CName.NameType, "CName NameType not as expected")
+	assert.Equal(t, test_user, asRep.CName.NameString[0], "CName NameType not as expected")
+	assert.Equal(t, 19, asRep.PAData[0].PADataType, "PADataType not as expected")
+	assert.Equal(t, 5, asRep.Ticket.TktVNO, "TktVNO not as expected")
+	assert.Equal(t, test_realm, asRep.Ticket.Realm, "Ticket Realm not as expected")
+	assert.Equal(t, 2, asRep.Ticket.SName.NameType, "Ticket service nametype not as expected")
+	assert.Equal(t, "krbtgt", asRep.Ticket.SName.NameString[0], "Ticket service name string not as expected")
+	assert.Equal(t, test_realm, asRep.Ticket.SName.NameString[1], "Ticket service name string not as expected")
+	assert.Equal(t, types.KrbDictionary.ETypesByName["aes256-cts-hmac-sha1-96"], asRep.Ticket.EncPart.EType, "Etype of ticket encrypted part not as expected")
+	assert.Equal(t, 1, asRep.Ticket.EncPart.KVNO, "Ticket encrypted part KVNO not as expected")
+	assert.Equal(t, types.KrbDictionary.ETypesByName["aes256-cts-hmac-sha1-96"], asRep.EncPart.EType, "Etype of encrypted part not as expected")
+	assert.Equal(t, 0, asRep.EncPart.KVNO, "Encrypted part KVNO not as expected")
+	err = asRep.DecryptEncPartWithPassword(test_user_password)
+	if err != nil {
+		t.Fatalf("Decryption of AS_REP EncPart failed: %v", err)
+	}
+	assert.Equal(t, 18, asRep.DecryptedEncPart.Key.KeyType, "KeyType in decrypted EncPart not as expected")
+	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.LastReqs[0].LRValue, "LastReqs did not have a time value")
+	assert.Equal(t, 2069991465, asRep.DecryptedEncPart.Nonce, "Nonce value not as expected")
+	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.KeyExpiration, "Key expriation not a time type")
+	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.AuthTime, "AuthTime not a time type")
+	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.StartTime, "StartTime not a time type")
+	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.EndTime, "StartTime not a time type")
+	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.RenewTill, "RenewTill not a time type")
+	assert.Equal(t, test_realm, asRep.DecryptedEncPart.SRealm, "Service realm not as expected")
+	assert.Equal(t, 2, asRep.DecryptedEncPart.SName.NameType, "Name type for AS_REP not as expected")
+	assert.Equal(t, []string{"krbtgt", test_realm}, asRep.DecryptedEncPart.SName.NameString, "Service name string not as expected")
+	//t.Log("Finished testing ecrypted parts of AS REP")
+
+	//TODO should we be able to decrypt this part with the client key?
+	/*s, err = etype.Decrypt(key, asRep.Ticket.EncPart.Cipher)
+	if err != nil {
+		t.Fatalf("Error decrypting ticket encrypted part: %v\n", err)
+	}
+	t.Logf("Decypted Ticket EncPart %+v", s)*/
+}
+
 //func TestKDCRep_Validate(t *testing.T) {
 //	d, _ := os.Getwd()
 //	asreqData, err := ioutil.ReadFile(d + "/../testdata/AS-REQ.raw")

+ 10 - 0
types/Cryptosystem.go

@@ -2,6 +2,7 @@ package types
 
 import (
 	"github.com/jcmturner/asn1"
+	"fmt"
 )
 
 // Reference: https://www.ietf.org/rfc/rfc4120.txt
@@ -31,6 +32,14 @@ func (a *EncryptedData) Unmarshal(b []byte) error {
 	return err
 }
 
+func (a *EncryptedData) Marshal() ([]byte, error) {
+	edb, err := asn1.Marshal(*a)
+	if err != nil {
+		return edb, fmt.Errorf("Error marshalling EncryptedData: %v", err)
+	}
+	return edb, nil
+}
+
 func (a *EncryptionKey) Unmarshal(b []byte) error {
 	_, err := asn1.Unmarshal(b, a)
 	return err
@@ -40,3 +49,4 @@ func (a *Checksum) Unmarshal(b []byte) error {
 	_, err := asn1.Unmarshal(b, a)
 	return err
 }
+

+ 13 - 0
types/PAData.go

@@ -23,6 +23,19 @@ type PAEncTSEnc struct {
 	PAUSec      int       `asn1:"explicit,optional,tag:1"`
 }
 
+func GetPAEncTSEncAsnMarshalled() ([]byte, error){
+	t := time.Now()
+	p := PAEncTSEnc{
+		PATimestamp: t,
+		PAUSec: int((t.UnixNano() / int64(time.Microsecond)) - (t.Unix() * 1e6)),
+	}
+	b, err := asn1.Marshal(p)
+	if err != nil {
+		return b, fmt.Errorf("Error mashalling PAEncTSEnc: %v", err)
+	}
+	return b, nil
+}
+
 type ETypeInfoEntry struct {
 	EType int    `asn1:"explicit,tag:0"`
 	Salt  []byte `asn1:"explicit,optional,tag:1"`