// Package crypto implements cryptographic functions for Kerberos 5 implementation.
package crypto import ( ) // GetEtype returns an instances of the required etype struct for the etype ID. func ( int32) (etype.EType, error) { switch { case etypeID.AES128_CTS_HMAC_SHA1_96: var Aes128CtsHmacSha96 return , nil case etypeID.AES256_CTS_HMAC_SHA1_96: var Aes256CtsHmacSha96 return , nil case etypeID.AES128_CTS_HMAC_SHA256_128: var Aes128CtsHmacSha256128 return , nil case etypeID.AES256_CTS_HMAC_SHA384_192: var Aes256CtsHmacSha384192 return , nil case etypeID.DES3_CBC_SHA1_KD: var Des3CbcSha1Kd return , nil case etypeID.RC4_HMAC: var RC4HMAC return , nil default: return nil, fmt.Errorf("unknown or unsupported EType: %d", ) } } // GetChksumEtype returns an instances of the required etype struct for the checksum ID. func ( int32) (etype.EType, error) { switch { case chksumtype.HMAC_SHA1_96_AES128: var Aes128CtsHmacSha96 return , nil case chksumtype.HMAC_SHA1_96_AES256: var Aes256CtsHmacSha96 return , nil case chksumtype.HMAC_SHA256_128_AES128: var Aes128CtsHmacSha256128 return , nil case chksumtype.HMAC_SHA384_192_AES256: var Aes256CtsHmacSha384192 return , nil case chksumtype.HMAC_SHA1_DES3_KD: var Des3CbcSha1Kd return , nil case chksumtype.KERB_CHECKSUM_HMAC_MD5: var RC4HMAC return , nil //case chksumtype.KERB_CHECKSUM_HMAC_MD5_UNSIGNED: // var et RC4HMAC // return et, nil default: return nil, fmt.Errorf("unknown or unsupported checksum type: %d", ) } } // GetKeyFromPassword generates an encryption key from the principal's password. func ( string, types.PrincipalName, string, int32, types.PADataSequence) (types.EncryptionKey, etype.EType, error) { var types.EncryptionKey , := GetEtype() if != nil { return , , fmt.Errorf("error getting encryption type: %v", ) } := .GetDefaultStringToKeyParams() var string var int32 for , := range { switch .PADataType { case patype.PA_PW_SALT: if > .PADataType { continue } = string(.PADataValue) case patype.PA_ETYPE_INFO: if > .PADataType { continue } var types.ETypeInfo := .Unmarshal(.PADataValue) if != nil { return , , fmt.Errorf("error unmashaling PA Data to PA-ETYPE-INFO2: %v", ) } if != [0].EType { , = GetEtype([0].EType) if != nil { return , , fmt.Errorf("error getting encryption type: %v", ) } } = string([0].Salt) case patype.PA_ETYPE_INFO2: if > .PADataType { continue } var types.ETypeInfo2 := .Unmarshal(.PADataValue) if != nil { return , , fmt.Errorf("error unmashalling PA Data to PA-ETYPE-INFO2: %v", ) } if != [0].EType { , = GetEtype([0].EType) if != nil { return , , fmt.Errorf("error getting encryption type: %v", ) } } if len([0].S2KParams) == 4 { = hex.EncodeToString([0].S2KParams) } = [0].Salt } } if == "" { = .GetSalt() } , := .StringToKey(, , ) if != nil { return , , fmt.Errorf("error deriving key from string: %+v", ) } = types.EncryptionKey{ KeyType: , KeyValue: , } return , , nil } // GetEncryptedData encrypts the data provided and returns and EncryptedData type. // Pass a usage value of zero to use the key provided directly rather than deriving one. func ( []byte, types.EncryptionKey, uint32, int) (types.EncryptedData, error) { var types.EncryptedData , := GetEtype(.KeyType) if != nil { return , fmt.Errorf("error getting etype: %v", ) } , , := .EncryptMessage(.KeyValue, , ) if != nil { return , } = types.EncryptedData{ EType: .KeyType, Cipher: , KVNO: , } return , nil } // DecryptEncPart decrypts the EncryptedData. func ( types.EncryptedData, types.EncryptionKey, uint32) ([]byte, error) { return DecryptMessage(.Cipher, , ) } // DecryptMessage decrypts the ciphertext and verifies the integrity. func ( []byte, types.EncryptionKey, uint32) ([]byte, error) { , := GetEtype(.KeyType) if != nil { return []byte{}, fmt.Errorf("error decrypting: %v", ) } , := .DecryptMessage(.KeyValue, , ) if != nil { return nil, fmt.Errorf("error decrypting: %v", ) } return , nil }