/// <summary> /// Decode the KRB_ERROR token got from application. /// </summary> /// <param name="errorToken">The token got from an application message. This argument cannot be null.</param> /// <returns>The decoded AP response.</returns> /// <exception cref="System.ArgumentNullException">Thrown when the input parameter is null.</exception> /// <exception cref="System.FormatException">Thrown when the errorToken is not valid.</exception> public KileKrbError ParseKrbError(byte[] errorToken) { if (errorToken == null) { throw new ArgumentNullException(nameof(errorToken)); } byte[] errorBody = KerberosUtility.VerifyGssApiTokenHeader(errorToken); // Check if it has a two-byte tok_id if (errorBody == null || errorBody.Length <= sizeof(TOK_ID)) { throw new FormatException("Not a valid KRB_ERROR token!"); } TOK_ID id = (TOK_ID)KerberosUtility.ConvertEndian(BitConverter.ToUInt16(errorBody, 0)); if (id != TOK_ID.KRB_ERROR) { throw new FormatException("Not a valid KRB_ERROR token!"); } errorBody = ArrayUtility.SubArray(errorBody, sizeof(TOK_ID)); var error = new KileKrbError(); error.FromBytes(errorBody); return(error); }
public KileApRequest CreateApRequest( ApOptions apOptions, ChecksumType checksumType, int seqNumber, ChecksumFlags flag, EncryptionKey subkey, AuthorizationData authorizationData) { var request = new KileApRequest(context); request.Authenticator = CreateAuthenticator( checksumType, seqNumber, flag, subkey, authorizationData, context.ApSessionKey, null); request.Request.ap_options = new APOptions(KerberosUtility.ConvertInt2Flags((int)apOptions)); request.Request.msg_type = new Asn1Integer((int)MsgType.KRB_AP_REQ); request.Request.pvno = new Asn1Integer(ConstValue.KERBEROSV5); request.Request.ticket = context.ApTicket; return(request); }
/// <summary> /// Create and send malformed Kpassword Request /// </summary> /// <param name="newPwd">The new password to change</param> public void SendMalformedKpasswordRequest(string newPwd) { KpasswordRequest pwdRequest = this.CreateKpasswordRequest(newPwd); //Change the protocol version number(hex constant 0x0001) to be 0xff80 pwdRequest.version = KerberosUtility.ConvertEndian(0xff80); this.SendPdu(pwdRequest); this.testSite.Log.Add(LogEntryKind.Comment, "Send malformed Kpassword request."); }
public KpasswordRequest CreateAuthErrorKpasswordRequest(string newPwd) { //Generate the subkey, which will be used to encrypt/decrypt KRB-PRIV message EncryptionKey subkey = KerberosUtility.MakeKey((EncryptionType)this.Context.Ticket.SessionKey.keytype.Value, "Password01!", "This is a salt"); Context.Subkey = subkey; Authenticator authenticator = CreateAuthenticator(this.Context.Ticket, null, subkey); KpasswordRequest request = new KpasswordRequest(this.Context.Ticket, authenticator, newPwd, true); return(request); }
public KileAsRequest CreateAsRequest(string sName, KDCOptions kdcOptions, Asn1SequenceOf <PA_DATA> paData, params EncryptionType[] encryptionTypes) { var request = new KileAsRequest(context); request.Request.msg_type = new Asn1Integer((int)MsgType.KRB_AS_REQ); request.Request.pvno = new Asn1Integer(ConstValue.KERBEROSV5); request.Request.padata = paData; request.Request.req_body = new KDC_REQ_BODY(); request.Request.req_body.kdc_options = kdcOptions; request.Request.req_body.nonce = new KerbUInt32((uint)Math.Abs((int)DateTime.Now.Ticks)); request.Request.req_body.till = new KerberosTime(ConstValue.TGT_TILL_TIME); request.Request.req_body.rtime = new KerberosTime(ConstValue.TGT_RTIME); request.Request.req_body.addresses = new HostAddresses(new HostAddress[1] { new HostAddress(new KerbInt32((int)AddressType.NetBios), new Asn1OctetString(Encoding.ASCII.GetBytes(System.Net.Dns.GetHostName()))) }); if (userName != null) { request.Request.req_body.cname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_PRINCIPAL), KerberosUtility.String2SeqKerbString(userName)); } if (domain != null) { request.Request.req_body.realm = new Realm(domain); } if (sName != null) { request.Request.req_body.sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName, domain)); } if (encryptionTypes != null) { var etypes = new KerbInt32[encryptionTypes.Length]; for (int i = 0; i < encryptionTypes.Length; i++) { etypes[i] = new KerbInt32((int)encryptionTypes[i]); } request.Request.req_body.etype = new Asn1SequenceOf <KerbInt32>(etypes); } return(request); }
public EncryptionKey GenerateKey(EncryptionKey baseKey) { if (baseKey == null || baseKey.keytype == null || baseKey.keyvalue == null || baseKey.keyvalue.Value == null) { return(null); } byte[] keyBuffer = KerberosUtility.GenerateRandomBytes((uint)baseKey.keyvalue.ByteArrayValue.Length); var newKey = new EncryptionKey(new KerbInt32(baseKey.keytype.Value), new Asn1OctetString(keyBuffer)); return(newKey); }
private EncTicketPart RetrieveAndDecryptServiceTicket(KerberosFunctionalClient kerberosClient, out EncryptionKey serviceKey) { //Create and send AS request const KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; kerberosClient.SendAsRequest(options, null); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client expects Kerberos Error from KDC"); //Receive preauthentication required error METHOD_DATA methodData; KerberosKrbError krbError = kerberosClient.ExpectPreauthRequiredError(out methodData); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client sends AS request with PA-DATA set"); //Create sequence of PA data string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp, 0, kerberosClient.Context.SelectedEType, kerberosClient.Context.CName.Password, kerberosClient.Context.CName.Salt); PaPacRequest paPacRequest = new PaPacRequest(true); Asn1SequenceOf <PA_DATA> seqOfPaData = new Asn1SequenceOf <PA_DATA>(new[] { paEncTimeStamp.Data, paPacRequest.Data }); //Create and send AS request kerberosClient.SendAsRequest(options, seqOfPaData); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client expects AS response from KDC"); KerberosAsResponse asResponse = kerberosClient.ExpectAsResponse(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create and send TGS request BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client sends TGS request to KDC"); kerberosClient.SendTgsRequest(servicePrincipalName, options); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client expects TGS response from KDC"); KerberosTgsResponse tgsResponse = kerberosClient.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(servicePrincipalName, KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname), "Service principal name in service ticket should match expected."); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Decrypt SMB2 Service Ticket"); serviceKey = keyManager.QueryKey(servicePrincipalName, TestConfig.DomainName, kerberosClient.Context.SelectedEType); tgsResponse.DecryptTicket(serviceKey); return(tgsResponse.TicketEncPart); }
private EncryptedData EncryptTicket(EncTicketPart encTicketPart, EncryptionKey serviceKey) { Asn1BerEncodingBuffer encodeBuffer = new Asn1BerEncodingBuffer(); encTicketPart.BerEncode(encodeBuffer, true); byte[] encData = KerberosUtility.Encrypt( (EncryptionType)serviceKey.keytype.Value, serviceKey.keyvalue.ByteArrayValue, encodeBuffer.Data, (int)KeyUsageNumber.AS_REP_TicketAndTGS_REP_Ticket); return(new EncryptedData( new KerbInt32(serviceKey.keytype.Value), null, new Asn1OctetString(encData))); }
public KileTgsRequest CreateTgsRequest(string sName, KDCOptions kdcOptions, Asn1SequenceOf <PA_DATA> paData, ChecksumType checksumType, Ticket additionalTicket, AuthorizationData authorizationData) { if (sName == null) { throw new ArgumentNullException(nameof(sName)); } var sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName.Split('/'))); return(CreateTgsRequest(sname, kdcOptions, new KerbUInt32((uint)Math.Abs((uint)DateTime.Now.Ticks)), context.UserRealm, paData, checksumType, additionalTicket, authorizationData)); }
/// <summary> /// Construct an kerbcred EncryptedData. /// </summary> /// <param name="key">The key to do encryption.</param> /// <returns>The EncKrbCredPart.</returns> private EncKrbCredPart ConstrutCredEncryptedData(EncryptionKey key) { var encKrbCred = new EncKrbCredPart(); encKrbCred.nonce = new KerbUInt32((uint)Math.Abs((int)DateTime.Now.Ticks)); encKrbCred.timestamp = new KerberosTime(KerberosUtility.GetCurrentUTCTime()); encKrbCred.usec = new Microseconds(0); encKrbCred.s_address = new HostAddress(new KerbInt32((int)AddressType.NetBios), new Asn1OctetString(Dns.GetHostName())); var krbCredInfo = new KrbCredInfo[1]; krbCredInfo[0] = new KrbCredInfo(); krbCredInfo[0].key = key; encKrbCred.ticket_info = new Asn1SequenceOf <KrbCredInfo>(krbCredInfo); return(encKrbCred); }
/// <summary> /// Construct PA_TGS_REQ for TGS request. /// </summary> /// <param name="cRealm">This field contains the name of the realm in which the client is registered and in /// which initial authentication took place.</param> /// <param name="cName">This field contains the name part of the client's principal identifier.</param> /// <param name="checksumType">The checksum type in Authenticator.</param> /// <param name="checksumBody">The data to compute checksum.</param> /// <returns>The constructed PaData.</returns> private PA_DATA ConstructTgsPaData(ChecksumType checksumType, byte[] checksumBody) { var request = new AP_REQ(); KerbAuthDataTokenRestrictions adRestriction = ConstructKerbAuthDataTokenRestrictions(0, (uint)LSAP_TOKEN_INFO_INTEGRITY_Flags.FULL_TOKEN, (uint)LSAP_TOKEN_INFO_INTEGRITY_TokenIL.Medium, new Guid().ToString()); AuthorizationData authData = ConstructAuthorizationData(adRestriction); // create and encrypt authenticator Authenticator authenticator = CreateAuthenticator( checksumType, 0, 0, null, authData, context.TgsSessionKey, checksumBody); var asnBuffPlainAuthenticator = new Asn1BerEncodingBuffer(); authenticator.BerEncode(asnBuffPlainAuthenticator, true); byte[] encAsnEncodedAuth = KerberosUtility.Encrypt((EncryptionType)context.TgsSessionKey.keytype.Value, context.TgsSessionKey.keyvalue.ByteArrayValue, asnBuffPlainAuthenticator.Data, (int)KeyUsageNumber.TG_REQ_PA_TGS_REQ_padataOR_AP_REQ_Authenticator); request.authenticator = new EncryptedData(); request.authenticator.etype = new Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.KerbInt32(context.TgsSessionKey.keytype.Value); request.authenticator.cipher = new Asn1OctetString(encAsnEncodedAuth); // create AP request request.ap_options = new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.None)); request.msg_type = new Asn1Integer((int)MsgType.KRB_AP_REQ); request.pvno = new Asn1Integer(ConstValue.KERBEROSV5); request.ticket = context.TgsTicket; var apBerBuffer = new Asn1BerEncodingBuffer(); request.BerEncode(apBerBuffer, true); return(new PA_DATA(new KerbInt32((int)PaDataType.PA_TGS_REQ), new Asn1OctetString(apBerBuffer.Data))); }
/// <summary> /// Make keys for given encryption types. /// </summary> /// <param name="principal">Principal name</param> /// <param name="realm">Realm</param> /// <param name="password">Password</param> /// <param name="salt">Salt</param> /// <param name="type">Encryption type</param> public void MakeKey(string principal, string realm, string password, string salt, EncryptionType type) { EncryptionKey key = KerberosUtility.MakeKey(type, password, salt); var ExistingKey = QueryKey(principal, realm, type); if (ExistingKey != null) { throw new Exception("Key already exists."); } KeytabItem item = new KeytabItem() { Principal = principal, Realm = realm.ToLower(), Kvno = 0, // Set to 0 for self generated keys. KeyType = type, Key = key }; keytabItems.Add(item); }
/// <summary> /// Construct EncKrbPrivPartof of KrbPrivRequest /// </summary> /// <param name="krbPrivRequest">to decide whether an seq_number in EncKrbPrivPart or not</param> /// <param name="userData">The user data want to send.</param> /// <returns>The EncKrbPrivPart.</returns> private EncKrbPrivPart ConstructEncKrbPrivPart(KRB_PRIV_REQUEST krbPrivRequest, byte[] userData) { var encKrbPriv = new EncKrbPrivPart(); encKrbPriv.s_address = new HostAddress(new KerbInt32((int)AddressType.NetBios), new Asn1OctetString(Dns.GetHostName())); encKrbPriv.usec = new Microseconds(0); encKrbPriv.user_data = new Asn1OctetString(userData); if (krbPrivRequest == KRB_PRIV_REQUEST.KrbPrivWithSequenceNumber) { encKrbPriv.seq_number = new KerbUInt32((long)context.CurrentLocalSequenceNumber); encKrbPriv.timestamp = null; } else { encKrbPriv.seq_number = null; encKrbPriv.timestamp = new KerberosTime(KerberosUtility.GetCurrentUTCTime()); } return(encKrbPriv); }
/// <summary> /// Create authenticator for AP request or part of PA-DATA for TGS request. /// </summary> /// <param name="cRealm">This field contains the name of the realm in which the client is registered and in /// which initial authentication took place.</param> /// <param name="cName">This field contains the name part of the client's principal identifier.</param> /// <param name="checksumType">The checksum type selected.</param> /// <param name="seqNumber">The current local sequence number.</param> /// <param name="flag">The flag set in checksum field of Authenticator.</param> /// <param name="subkey">Specify the new subkey used in the following exchange. This field is optional. /// This argument can be got with method GenerateKey(ApSessionKey). /// This argument can be null. If this argument is null, no subkey will be sent.</param> /// <param name="authorizationData">The authentication data of authenticator. This field is optional. /// This argument can be generated by method ConstructAuthorizationData. This argument can be null. /// If this argument is null, no Authorization Data will be sent.</param> /// <param name="key">The key to do checksum.</param> /// <param name="checksumBody">The data to compute checksum.</param> /// <returns>The created authenticator.</returns> private Authenticator CreateAuthenticator( ChecksumType checksumType, int seqNumber, ChecksumFlags flag, EncryptionKey subkey, AuthorizationData authorizationData, EncryptionKey key, byte[] checksumBody) { var plaintextAuthenticator = CreateAuthenticator(authorizationData, subkey, seqNumber); if (checksumType == ChecksumType.ap_authenticator_8003) { // compute the checksum var checksum = new AuthCheckSum(); checksum.Lgth = ConstValue.AUTHENTICATOR_CHECKSUM_LENGTH; checksum.Bnd = new byte[checksum.Lgth]; checksum.Flags = (int)flag; byte[] checkData = ArrayUtility.ConcatenateArrays(BitConverter.GetBytes(checksum.Lgth), checksum.Bnd, BitConverter.GetBytes(checksum.Flags)); // in AP request plaintextAuthenticator.cksum = new Checksum(new KerbInt32((int)checksumType), new Asn1OctetString(checkData)); } else { // in TGS PA data byte[] checkData = KerberosUtility.GetChecksum( key.keyvalue.ByteArrayValue, checksumBody, (int)KeyUsageNumber.TGS_REQ_PA_TGS_REQ_adataOR_AP_REQ_Authenticator_cksum, checksumType); plaintextAuthenticator.cksum = new Checksum(new KerbInt32((int)checksumType), new Asn1OctetString(checkData)); } return(plaintextAuthenticator); }
public KileAsResponse CreateAsResponse( KileConnection kileConnection, KileAccountType accountType, string password, Asn1SequenceOf <PA_DATA> SeqofPaData, EncTicketFlags encTicketFlags, AuthorizationData ticketAuthorizationData) { KileServerContext serverContext = GetServerContextByKileConnection(kileConnection); string cName = serverContext.UserName.name_string.Elements[0].Value; string cRealm = serverContext.UserRealm.Value; serverContext.Salt = GenerateSalt(cRealm, cName, accountType); serverContext.TicketEncryptKey = new EncryptionKey(new KerbInt32((int)EncryptionType.RC4_HMAC), new Asn1OctetString(GetEncryptionKeyByType(EncryptionType.RC4_HMAC))); if (password == null) { throw new ArgumentNullException(nameof(password)); } else { serverContext.Password = password; } KileAsResponse response = new KileAsResponse(serverContext); // Construct a Ticket var ticket = new Ticket(); ticket.tkt_vno = new Asn1Integer(ConstValue.KERBEROSV5); ticket.realm = new Realm(domain); ticket.sname = serverContext.SName; // Set EncTicketPart var encTicketPart = new EncTicketPart(); EncryptionType encryptionType = (EncryptionType)serverContext.EncryptType.Elements[0].Value; encTicketPart.key = new EncryptionKey(new KerbInt32((int)encryptionType), new Asn1OctetString(GetEncryptionKeyByType(encryptionType))); encTicketPart.flags = new TicketFlags(KerberosUtility.ConvertInt2Flags((int)encTicketFlags)); encTicketPart.crealm = serverContext.UserRealm; encTicketPart.cname = serverContext.UserName; encTicketPart.transited = new TransitedEncoding(new KerbInt32(4), null); encTicketPart.authtime = KerberosUtility.CurrentKerberosTime; encTicketPart.starttime = KerberosUtility.CurrentKerberosTime; encTicketPart.endtime = serverContext.endTime; encTicketPart.renew_till = serverContext.rtime ?? encTicketPart.endtime; encTicketPart.caddr = serverContext.Addresses; encTicketPart.authorization_data = ticketAuthorizationData; response.TicketEncPart = encTicketPart; // Set AS_REP response.Response.pvno = new Asn1Integer(ConstValue.KERBEROSV5); response.Response.msg_type = new Asn1Integer((int)MsgType.KRB_AS_RESP); response.Response.padata = SeqofPaData; response.Response.crealm = serverContext.UserRealm; response.Response.cname = serverContext.UserName; response.Response.ticket = ticket; // Set EncASRepPart var encASRepPart = new EncASRepPart(); encASRepPart.key = encTicketPart.key; var element = new LastReqElement(new KerbInt32(0), KerberosUtility.CurrentKerberosTime); encASRepPart.last_req = new LastReq(new LastReqElement[] { element }); encASRepPart.nonce = serverContext.Nonce; encASRepPart.flags = encTicketPart.flags; encASRepPart.authtime = encTicketPart.authtime; encASRepPart.starttime = encTicketPart.starttime; encASRepPart.endtime = encTicketPart.endtime; encASRepPart.renew_till = encTicketPart.renew_till; encASRepPart.srealm = ticket.realm; encASRepPart.sname = ticket.sname; encASRepPart.caddr = encTicketPart.caddr; response.EncPart = encASRepPart; return(response); }
/// <summary> /// Initialize the context from a token. /// </summary> /// <param name="inToken">The token used to initialize.</param> /// <exception cref="System.NotSupportedException">Thrown when the ContextAttribute contains a flag that not be /// supported.</exception> /// <exception cref="System.InvalidOperationException">Thrown when an error is returned.</exception> public override void Initialize(byte[] inToken) { if (inToken == null || inToken.Length == 0) { KilePdu response = null; string sname = ConstValue.KERBEROS_SNAME; KileAsRequest asRequest; EncryptionKey subkey = null; // Create and send AS request for pre-authentication KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.RENEWABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLEOK; KDCOptions flags = new KDCOptions(KerberosUtility.ConvertInt2Flags((int)options)); // Create and send AS request for pre-authentication asRequest = client.CreateAsRequest(sname, flags, null, this.GetClientSupportedEtype()); client.SendPdu(asRequest); response = client.ExpectPdu(ConstValue.TIMEOUT_DEFAULT); KileKrbError preAuthError = response as KileKrbError; if ((preAuthError == null) || (!preAuthError.ErrorCode.Equals(KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED))) { throw new InvalidOperationException("The Error code should be KDC_ERR_PREAUTH_REQUIRED"); } // Create and send AS request for TGT var defualtEncryptType = (client.ClientContext.TgsSessionKey == null) ? EncryptionType.RC4_HMAC : (EncryptionType)client.ClientContext.TgsSessionKey.keytype.Value; PaEncTimeStamp timestamp = client.ConstructPaEncTimeStamp(defualtEncryptType); PaPacRequest pacRequest = client.ConstructPaPacRequest(true); Asn1SequenceOf <PA_DATA> paData = client.ConstructPaData(timestamp, pacRequest); if ((contextAttribute & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle) { asRequest = client.CreateAsRequest(sname, flags, paData, this.GetClientSupportedEtype()); //subkey = new EncryptionKey((int)EncryptionType.AES256_CTS_HMAC_SHA1_96, // KileUtility.GenerateRandomBytes(ConstValue.AES_KEY_LENGTH)); var key = KeyGenerator.MakeKey(EncryptionType.AES256_CTS_HMAC_SHA1_96, client.ClientContext.Password, client.ClientContext.Salt); subkey = new EncryptionKey(new KerbInt32((long)EncryptionType.AES256_CTS_HMAC_SHA1_96), new Asn1OctetString(key)); } else { asRequest = client.CreateAsRequest(sname, flags, paData, this.GetClientSupportedEtype()); } client.SendPdu(asRequest); response = client.ExpectPdu(ConstValue.TIMEOUT_DEFAULT); if (response.GetType() == typeof(KileKrbError)) { throw new InvalidOperationException("Received Kerberos Error response: " + ((KileKrbError)response).ErrorCode); } KileAsResponse asResponse = (KileAsResponse)response; // Create and send TGS request // for example: "KERB.COMldapsut02.kerb.com" client.ClientContext.Salt = domain.ToUpper(); string[] nameList = userLogonName.Split('/'); foreach (string name in nameList) { client.ClientContext.Salt += name; } KileTgsRequest tgsRequest = client.CreateTgsRequest(this.serverName, flags, null, ChecksumType.hmac_md5_string, null, null); client.SendPdu(tgsRequest); response = client.ExpectPdu(ConstValue.TIMEOUT_DEFAULT); if (response.GetType() == typeof(KileKrbError)) { throw new InvalidOperationException("Received Kerberos Error response: " + ((KileKrbError)response).ErrorCode); } KileTgsResponse tgsResponse = (KileTgsResponse)response; ApOptions apOption; ChecksumFlags checksumFlag; GetFlagsByContextAttribute(out apOption, out checksumFlag); KerbAuthDataTokenRestrictions adRestriction = client.ConstructKerbAuthDataTokenRestrictions(0, (uint)LSAP_TOKEN_INFO_INTEGRITY_Flags.FULL_TOKEN, (uint)LSAP_TOKEN_INFO_INTEGRITY_TokenIL.Medium, new Guid().ToString()); AdAuthDataApOptions adApOptions = client.ConstructAdAuthDataApOptions(ConstValue.KERB_AP_OPTIONS_CBT); AuthorizationData authData = client.ConstructAuthorizationData(adRestriction, adApOptions); KileApRequest apRequest = client.CreateApRequest(apOption, ChecksumType.ap_authenticator_8003, ConstValue.SEQUENCE_NUMBER_DEFAULT, checksumFlag, subkey, authData); token = apRequest.ToBytes(); bool isMutualAuth = (contextAttribute & ClientSecurityContextAttribute.MutualAuth) == ClientSecurityContextAttribute.MutualAuth; bool isDceStyle = (contextAttribute & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle; if (isMutualAuth || isDceStyle) { continueProcess = true; // SEC_I_CONTINUE_NEEDED; } else { continueProcess = false; // SEC_E_OK; } } else // mutual authentication { KileApResponse apResponse = client.ParseApResponse(inToken); token = null; if ((contextAttribute & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle) { KileApResponse apResponseSend = client.CreateApResponse(null); token = apResponseSend.ToBytes(); } this.continueProcess = false; // SEC_E_OK; } }
private void CrossRealm_Smb2_AccessFile(string localRealmName, string trustuedRealmName, User localUser, Computer localKDC, Computer trustedKDC, TransportType transportType, FileServer fileserverInTrustedRealm, string filePath, string fileName, bool expectAccessDeny) { base.Logging(); client = new KerberosTestClient(localRealmName, localUser.Username, localUser.Password, KerberosAccountType.User, localKDC.IPAddress, localKDC.Port, transportType, testConfig.SupportedOid); //Create and send AS request KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); //Recieve preauthentication required error METHOD_DATA methodData; KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData); //Create sequence of PA data string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp, 0, this.client.Context.SelectedEType, this.client.Context.CName.Password, this.client.Context.CName.Salt); PaPacRequest paPacRequest = new PaPacRequest(true); Asn1SequenceOf <PA_DATA> seqOfPaData = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data }); //Create and send AS request client.SendAsRequest(options, seqOfPaData); KerberosAsResponse asResponse = client.ExpectAsResponse(); //Create and send TGS request if (this.testConfig.TrustType == Adapter.TrustType.Forest) { client.SendTgsRequest(fileserverInTrustedRealm.Smb2ServiceName, options); } else if (this.testConfig.TrustType == Adapter.TrustType.Realm) { client.SendTgsRequest(trustedKDC.DefaultServiceName, options); } BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send TGS request"); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); BaseTestSite.Log.Add(LogEntryKind.Comment, "Receive a referral TGS response."); BaseTestSite.Assert.AreEqual(trustedKDC.DefaultServiceName, KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname), "The service principal name in referral ticket should match expected."); BaseTestSite.Assert.AreEqual(localRealmName.ToLower(), tgsResponse.Response.ticket.realm.Value.ToLower(), "The realm name in referral ticket should match expected."); //Change realm client.ChangeRealm(trustuedRealmName, trustedKDC.IPAddress, trustedKDC.Port, this.testConfig.TransportType); //Create and send referral TGS request client.SendTgsRequest(fileserverInTrustedRealm.Smb2ServiceName, options); KerberosTgsResponse refTgsResponse = client.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(fileserverInTrustedRealm.Smb2ServiceName, KerberosUtility.PrincipalName2String(refTgsResponse.Response.ticket.sname), "The service principal name in service ticket should match expected."); BaseTestSite.Assert.AreEqual(trustuedRealmName.ToLower(), refTgsResponse.Response.ticket.realm.Value.ToLower(), "The realm name in service ticket should match expected."); EncryptionKey key = testConfig.QueryKey(fileserverInTrustedRealm.Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType); refTgsResponse.DecryptTicket(key); BaseTestSite.Assert.AreEqual(localRealmName.ToLower(), refTgsResponse.TicketEncPart.crealm.Value.ToLower(), "Realm name in service ticket encrypted part should match expected."); BaseTestSite.Assert.AreEqual(localUser.Username.ToLower(), KerberosUtility.PrincipalName2String(refTgsResponse.TicketEncPart.cname).ToLower(), "User name in service ticket encrypted part should match expected."); AuthorizationData data = null; EncryptionKey subkey = KerberosUtility.GenerateKey(client.Context.SessionKey); byte[] token = client.CreateGssApiToken(ApOptions.MutualRequired, data, subkey, ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG); BaseTestSite.Log.Add(LogEntryKind.Comment, "Logon to fileserver and Access File."); AccessFile(filePath, fileName, fileserverInTrustedRealm, token, refTgsResponse.EncPart.key, expectAccessDeny); }
private void CBAC_Smb2_AccessFile(string RealmName, User user, Computer kdc, TransportType transportType, FileServer fileserver, string filePath, string fileName, bool expectAccessDeny) { base.Logging(); client = new KerberosTestClient(RealmName, user.Username, user.Password, KerberosAccountType.User, kdc.IPAddress, kdc.Port, transportType, testConfig.SupportedOid); KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); METHOD_DATA methodData; KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send AS request with PaEncTimeStamp, PaPacRequest and paPacOptions."); string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp, 0, client.Context.SelectedEType, client.Context.CName.Password, this.client.Context.CName.Salt); PaPacRequest paPacRequest = new PaPacRequest(true); PaPacOptions paPacOptions = new PaPacOptions(PacOptions.Claims | PacOptions.ForwardToFullDc); Asn1SequenceOf <PA_DATA> seqOfPaData = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data, paPacOptions.Data }); client.SendAsRequest(options, seqOfPaData); KerberosAsResponse asResponse = client.ExpectAsResponse(); //Verify encrypted padata PaSupportedEncTypes paSupportedEncTypes = null; BaseTestSite.Assert.IsNotNull(asResponse.EncPart, "The encrypted part of AS-REP is decrypted."); BaseTestSite.Assert.IsNotNull(asResponse.EncPart.pa_datas, "The encrypted padata is not null."); if (this.testConfig.IsKileImplemented) { foreach (var padata in asResponse.EncPart.pa_datas.Elements) { var parsedPadata = PaDataParser.ParseRepPaData(padata); if (parsedPadata is PaSupportedEncTypes) { paSupportedEncTypes = parsedPadata as PaSupportedEncTypes; } } BaseTestSite.Assert.IsNotNull(paSupportedEncTypes, "The encrypted padata of AS-REP contains PA_SUPPORTED_ENCTYPES."); if (this.testConfig.IsClaimSupported) { BaseTestSite.Assert.IsTrue( paSupportedEncTypes.SupportedEncTypes.HasFlag(SupportedEncryptionTypes.Claims_Supported), "Claims is supported."); } } //TGS exchange BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send FAST armored TGS request: {0}.", fileserver.Smb2ServiceName); Asn1SequenceOf <PA_DATA> seqOfPaData2 = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paPacRequest.Data, paPacOptions.Data }); client.SendTgsRequest(fileserver.Smb2ServiceName, options, seqOfPaData2); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); EncryptionKey key = testConfig.QueryKey(fileserver.Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType); tgsResponse.DecryptTicket(key); BaseTestSite.Assert.IsNotNull(tgsResponse.EncPart, "The encrypted part of TGS-REP is decrypted."); //Verify TGS encryped padata paSupportedEncTypes = null; BaseTestSite.Assert.IsNotNull(tgsResponse.EncPart, "The encrypted part of TGS-REP is decrypted."); BaseTestSite.Assert.IsNotNull(tgsResponse.EncPart.pa_datas, "The encrypted padata of TGS-REP is not null."); if (this.testConfig.IsKileImplemented) { foreach (var padata in tgsResponse.EncPart.pa_datas.Elements) { var parsedPadata = PaDataParser.ParseRepPaData(padata); if (parsedPadata is PaSupportedEncTypes) { paSupportedEncTypes = parsedPadata as PaSupportedEncTypes; } } BaseTestSite.Assert.IsNotNull(paSupportedEncTypes, "The encrypted padata of TGS-REP contains PA_SUPPORTED_ENCTYPES."); } if (this.testConfig.IsKileImplemented) { BaseTestSite.Assert.IsNotNull(tgsResponse.TicketEncPart.authorization_data, "The ticket contains Authorization data."); AdWin2KPac adWin2kPac = FindOneInAuthData <AdWin2KPac>(tgsResponse.TicketEncPart.authorization_data.Elements); BaseTestSite.Assert.IsNotNull(adWin2kPac, "The Authorization data contains AdWin2KPac."); } AuthorizationData data = null; EncryptionKey subkey = KerberosUtility.GenerateKey(client.Context.SessionKey); byte[] token = client.CreateGssApiToken(ApOptions.MutualRequired, data, subkey, ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG); BaseTestSite.Log.Add(LogEntryKind.Comment, "Logon to fileserver and Access File."); AccessFile(filePath, fileName, fileserver, token, tgsResponse.EncPart.key, expectAccessDeny); }
private void DAC_Smb2_AccessFile(string RealmName, User user, Computer kdc, TransportType transportType, FileServer fileserver, string filePath, string fileName, bool expectAccessDeny) { base.Logging(); client = new KerberosTestClient(RealmName, user.Username, user.Password, KerberosAccountType.User, kdc.IPAddress, kdc.Port, transportType, testConfig.SupportedOid); //Create and send AS request KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); //Recieve preauthentication required error METHOD_DATA methodData; KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData); //Create sequence of PA data string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp, 0, client.Context.SelectedEType, this.client.Context.CName.Password, this.client.Context.CName.Salt); PaPacRequest paPacRequest = new PaPacRequest(true); Asn1SequenceOf <PA_DATA> seqOfPaData = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data }); //Create and send AS request client.SendAsRequest(options, seqOfPaData); KerberosAsResponse asResponse = client.ExpectAsResponse(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create and send TGS request client.SendTgsRequest(fileserver.Smb2ServiceName, options); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(fileserver.Smb2ServiceName, KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname), "Service principal name in service ticket should match expected."); EncryptionKey key = testConfig.QueryKey(fileserver.Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType); tgsResponse.DecryptTicket(key); BaseTestSite.Assert.AreEqual(RealmName.ToLower(), tgsResponse.TicketEncPart.crealm.Value.ToLower(), "Realm name in service ticket encrypted part should match expected."); BaseTestSite.Assert.AreEqual(user.Username.ToLower(), KerberosUtility.PrincipalName2String(tgsResponse.TicketEncPart.cname).ToLower(), "User name in service ticket encrypted part should match expected."); //Assert authorization data if (this.testConfig.IsKileImplemented) { BaseTestSite.Assert.IsNotNull(tgsResponse.TicketEncPart.authorization_data, "The ticket contains Authorization data."); AdWin2KPac adWin2kPac = FindOneInAuthData <AdWin2KPac>(tgsResponse.TicketEncPart.authorization_data.Elements); BaseTestSite.Assert.IsNotNull(adWin2kPac, "The Authorization data contains AdWin2KPac."); } AuthorizationData data = null; EncryptionKey subkey = KerberosUtility.GenerateKey(client.Context.SessionKey); byte[] token = client.CreateGssApiToken(ApOptions.MutualRequired, data, subkey, ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG); BaseTestSite.Log.Add(LogEntryKind.Comment, "Logon to fileserver and Access File."); AccessFile(filePath, fileName, fileserver, token, tgsResponse.EncPart.key, expectAccessDeny); }
private void claimsTest_Kerberos_CrossRealm_ADSource_User_Only(bool ctaFromConfig) { client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[2].Username, this.testConfig.LocalRealm.User[2].Password, KerberosAccountType.User, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); //Create and send AS request KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); //Recieve preauthentication required error METHOD_DATA methodData; KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData); //Create sequence of PA data string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp, 0, this.client.Context.SelectedEType, this.client.Context.CName.Password, this.client.Context.CName.Salt); PaPacRequest paPacRequest = new PaPacRequest(true); PaPacOptions paPacOptions = new PaPacOptions(PacOptions.Claims | PacOptions.ForwardToFullDc); Asn1SequenceOf <PA_DATA> seqOfPaData = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data, paPacOptions.Data }); //Create and send AS request client.SendAsRequest(options, seqOfPaData); KerberosAsResponse asResponse = client.ExpectAsResponse(); Asn1SequenceOf <PA_DATA> seqOfPaData2 = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data }); //Create and send TGS request client.SendTgsRequest(this.testConfig.TrustedRealm.KDC[0].DefaultServiceName, options, seqOfPaData2); BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send TGS request"); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); BaseTestSite.Log.Add(LogEntryKind.Comment, "Receive a referral TGS response."); BaseTestSite.Assert.AreEqual(this.testConfig.TrustedRealm.KDC[0].DefaultServiceName, KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname), "The service principal name in referral ticket should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), tgsResponse.Response.ticket.realm.Value.ToLower(), "The realm name in referral ticket should match expected."); EncryptionKey key = testConfig.QueryKey(this.testConfig.TrustedRealm.KDC[0].DefaultServiceName + "@" + this.testConfig.LocalRealm.RealmName, client.Context.Realm.ToString(), client.Context.SelectedEType); tgsResponse.DecryptTicket(key); CLAIMS_SET claims = new CLAIMS_SET(); AdWin2KPac adWin2kPac = FindOneInAuthData <AdWin2KPac>(tgsResponse.TicketEncPart.authorization_data.Elements); bool foundClaims = false; foreach (PacInfoBuffer buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf.GetType() == typeof(ClientClaimsInfo)) { claims = ((ClientClaimsInfo)buf).NativeClaimSet; foundClaims = true; } } BaseTestSite.Assert.IsTrue(foundClaims, "Found claims in referral TGS Ticket"); foundClaims = false; #region genertaed transformed claims Dictionary <string, string> expectedClaims = new Dictionary <string, string>(); if (!ctaFromConfig) { ClaimTransformer transformer = new ClaimTransformer(this.testConfig.TrustedRealm.KDC[0].IPAddress, this.testConfig.TrustedRealm.RealmName, this.testConfig.TrustedRealm.Admin.Username, this.testConfig.TrustedRealm.Admin.Password); List <CLAIMS_ARRAY> transformed = null; BaseTestSite.Assert.AreEqual <Win32ErrorCode_32>(Win32ErrorCode_32.ERROR_SUCCESS, transformer.TransformClaimsOnTrustTraversal(claims.ClaimsArrays, this.testConfig.LocalRealm.RealmName, true, out transformed), "should successfully transform claims"); foreach (CLAIMS_ARRAY array in transformed) { foreach (CLAIM_ENTRY entry in array.ClaimEntries) { string id = entry.Id; string value = null; switch (entry.Type) { case CLAIM_TYPE.CLAIM_TYPE_BOOLEAN: value = entry.Values.Struct4.BooleanValues[0].ToString(); break; case CLAIM_TYPE.CLAIM_TYPE_INT64: value = entry.Values.Struct1.Int64Values[0].ToString(); break; case CLAIM_TYPE.CLAIM_TYPE_STRING: value = entry.Values.Struct3.StringValues[0].ToString(); break; case CLAIM_TYPE.CLAIM_TYPE_UINT64: value = entry.Values.Struct2.Uint64Values[0].ToString(); break; default: BaseTestSite.Assert.Fail("Found invalid claim type during transform, value:" + (int)entry.Type); break; } expectedClaims.Add(id.ToLower(), value.ToLower()); } } } else { string[] tmp = this.testConfig.LocalRealm.User[2].TransformedClaims.ToLower().Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); BaseTestSite.Assert.IsTrue(tmp != null && tmp.Length % 2 == 0, "Claim.Crossforest.TransformedClaims in PTFConfig should be valid and not empty"); for (int i = 0; i < tmp.Length; i += 2) { expectedClaims.Add(tmp[i], tmp[i + 1]); } } #endregion //Change realm client.ChangeRealm(this.testConfig.TrustedRealm.RealmName, this.testConfig.TrustedRealm.KDC[0].IPAddress, this.testConfig.TrustedRealm.KDC[0].Port, this.testConfig.TransportType); //Create and send referal TGS request client.SendTgsRequest(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, options); KerberosTgsResponse refTgsResponse = client.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, KerberosUtility.PrincipalName2String(refTgsResponse.Response.ticket.sname), "The service principal name in service ticket should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.TrustedRealm.RealmName.ToLower(), refTgsResponse.Response.ticket.realm.Value.ToLower(), "The realm name in service ticket should match expected."); key = testConfig.QueryKey(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType); refTgsResponse.DecryptTicket(key); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(), refTgsResponse.TicketEncPart.crealm.Value.ToLower(), "Realm name in service ticket encrypted part should match expected."); BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[2].Username, KerberosUtility.PrincipalName2String(refTgsResponse.TicketEncPart.cname).ToLower(), "User name in service ticket encrypted part should match expected."); adWin2kPac = FindOneInAuthData <AdWin2KPac>(refTgsResponse.TicketEncPart.authorization_data.Elements); foreach (PacInfoBuffer buf in adWin2kPac.Pac.PacInfoBuffers) { if (buf.GetType() == typeof(ClientClaimsInfo)) { foundClaims = true; claims = ((ClientClaimsInfo)buf).NativeClaimSet; } } int errors = 0; BaseTestSite.Assert.IsTrue(foundClaims, "Found claims in reference TGS Ticket"); for (int i = 0; i < claims.ClaimsArrays[0].ClaimEntries.Length; i++) { string claimvalue = null; if (!expectedClaims.TryGetValue(claims.ClaimsArrays[0].ClaimEntries[i].Id.ToLower(), out claimvalue)) { errors++; BaseTestSite.Log.Add(LogEntryKind.CheckFailed, "Found unexpected claim with id: " + claims.ClaimsArrays[0].ClaimEntries[i].Id + " after transform"); } else { if (claimvalue != claims.ClaimsArrays[0].ClaimEntries[i].Values.Struct3.StringValues[0].ToLower()) { errors++; BaseTestSite.Log.Add( LogEntryKind.CheckFailed, "Value of claim \"" + claims.ClaimsArrays[0].ClaimEntries[i].Id + "\" is not expected, expected: " + claimvalue + " ,actual: " + claims.ClaimsArrays[0].ClaimEntries[i].Values.Struct3.StringValues[0]); } expectedClaims.Remove(claims.ClaimsArrays[0].ClaimEntries[i].Id); } } BaseTestSite.Assert.AreEqual(expectedClaims.Count, claims.ClaimsArrays[0].ClaimEntries.Count(), "Claims count should be equal."); BaseTestSite.Assert.AreEqual <int>(0, errors, "Expect no error should be found when compare claims from reference TGS ticket"); }
public KileTgsRequest CreateTgsRequest( PrincipalName sName, KDCOptions kdcOptions, KerbUInt32 nonce, Realm realm, Asn1SequenceOf <PA_DATA> paData, ChecksumType checksumType, Ticket additionalTicket, AuthorizationData authorizationData) { if (sName == null) { throw new ArgumentNullException(nameof(sName)); } if (realm == null) { throw new ArgumentNullException(nameof(realm)); } var request = new KileTgsRequest(context); request.Request.msg_type = new Asn1Integer((int)MsgType.KRB_TGS_REQ); request.Request.pvno = new Asn1Integer(ConstValue.KERBEROSV5); #region construct req_body request.Request.req_body = new KDC_REQ_BODY(); request.Request.req_body.kdc_options = kdcOptions; request.Request.req_body.nonce = nonce; request.Request.req_body.till = new KerberosTime(ConstValue.TGT_TILL_TIME); request.Request.req_body.etype = context.ClientEncryptionTypes; request.Request.req_body.realm = realm; if (additionalTicket != null) { request.Request.req_body.additional_tickets = new Asn1SequenceOf <Ticket>(new Ticket[] { additionalTicket }); } request.Request.req_body.sname = sName; request.EncAuthorizationData = authorizationData; if (authorizationData != null) { var asnBuffer = new Asn1BerEncodingBuffer(); authorizationData.BerEncode(asnBuffer, true); request.Request.req_body.enc_authorization_data = new EncryptedData(); request.Request.req_body.enc_authorization_data.etype = new KerbInt32(0); byte[] encAsnEncoded = asnBuffer.Data; if (context.TgsSessionKey != null && context.TgsSessionKey.keytype != null && context.TgsSessionKey.keyvalue != null && context.TgsSessionKey.keyvalue.Value != null) { encAsnEncoded = KerberosUtility.Encrypt((EncryptionType)context.TgsSessionKey.keytype.Value, context.TgsSessionKey.keyvalue.ByteArrayValue, asnBuffer.Data, (int)KeyUsageNumber.TGS_REQ_KDC_REQ_BODY_AuthorizationData); request.Request.req_body.enc_authorization_data.etype = new KerbInt32(context.TgsSessionKey.keytype.Value); } request.Request.req_body.enc_authorization_data.cipher = new Asn1OctetString(encAsnEncoded); } #endregion construct req_body #region construct PA_DATA var bodyBuffer = new Asn1BerEncodingBuffer(); request.Request.req_body.BerEncode(bodyBuffer); PA_DATA tgsPaData = ConstructTgsPaData(checksumType, bodyBuffer.Data); request.Request.padata = new Asn1SequenceOf <PA_DATA>(); if (paData == null || paData.Elements == null || paData.Elements.Length == 0) { request.Request.padata.Elements = new PA_DATA[] { tgsPaData }; } else { request.Request.padata.Elements = new PA_DATA[paData.Elements.Length + 1]; Array.Copy(paData.Elements, request.Request.padata.Elements, paData.Elements.Length); request.Request.padata.Elements[paData.Elements.Length] = tgsPaData; } #endregion construct PA_DATA return(request); }
private void Smb2KerberosAuthentication(CaseVariant variant) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Initialize Kerberos Functional Client"); KerberosFunctionalClient kerberosClient = new KerberosFunctionalClient( TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, KerberosAccountType.User, KDCIP, KDCPort, TransportType.TCP, OidPkt, BaseTestSite); #region Service Ticket EncryptionKey serviceKey; EncTicketPart encTicketPart = RetrieveAndDecryptServiceTicket(kerberosClient, out serviceKey); Ticket serviceTicket = kerberosClient.Context.Ticket.Ticket; Realm crealm = serviceTicket.realm; BaseTestSite.Assert.AreEqual(TestConfig.DomainName.ToLower(), encTicketPart.crealm.Value.ToLower(), "Realm name in service ticket encrypted part should match as expected, case insensitive"); BaseTestSite.Assert.AreEqual(TestConfig.UserName.ToLower(), KerberosUtility.PrincipalName2String(encTicketPart.cname).ToLower(), "User name in service ticket encrypted part should match as expected, case insensitive."); if (variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_TKT)) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Add a type-unknown AuthorizationData to the ticket"); AuthorizationDataElement unknownElement = GenerateUnKnownAuthorizationDataElement(); AppendNewAuthDataElement(encTicketPart.authorization_data, unknownElement); } if (variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_TKT_OPTIONAL)) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Add a type-unknown AuthorizationData which is inside AD_IF_RELEVANT to the ticket"); AuthorizationDataElement unknownElement = GenerateUnKnownAuthorizationDataElement(); AD_IF_RELEVANT ifRelavantElement = new AD_IF_RELEVANT(new[] { unknownElement }); var dataBuffer = new Asn1BerEncodingBuffer(); ifRelavantElement.BerEncode(dataBuffer); AuthorizationDataElement unknownElementOptional = new AuthorizationDataElement(new KerbInt32((long)AuthorizationData_elementType.AD_IF_RELEVANT), new Asn1OctetString(dataBuffer.Data)); AppendNewAuthDataElement(encTicketPart.authorization_data, unknownElementOptional); } if (variant.HasFlag(CaseVariant.TICKET_NOT_VALID)) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Change the Ticket start time to tomorrow"); DateTime tomorrow = DateTime.Now.AddDays(1); string kerbTimeString = tomorrow.ToUniversalTime().ToString("yyyyMMddhhmmssZ"); encTicketPart.starttime = new KerberosTime(kerbTimeString, true); } if (variant.HasFlag(CaseVariant.TICKET_EXPIRED)) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Change the Ticket end time to yesterday"); DateTime yesterday = DateTime.Now.AddDays(-1); string kerbTimeString = yesterday.ToUniversalTime().ToString("yyyyMMddhhmmssZ"); encTicketPart.endtime = new KerberosTime(kerbTimeString, true); } if (variant.HasFlag(CaseVariant.TICKET_WRONG_ENC_KEY)) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Modify the Ticket, making it encrypted with wrong key"); serviceKey = KerberosUtility.GenerateKey(serviceKey); } EncryptedData data = EncryptTicket(encTicketPart, serviceKey); serviceTicket.enc_part = data; if (variant.HasFlag(CaseVariant.TICKET_WRONG_REALM)) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Change the Realm in the Ticket to an unknown realm"); serviceTicket.realm = new Realm("kerb.com"); } if (variant.HasFlag(CaseVariant.TICKET_WRONG_SNAME)) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Change the SNAME in the Ticket to an unknown service name"); serviceTicket.sname = new PrincipalName(new KerbInt32((long)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString("UnknownService", TestConfig.DomainName)); } if (variant.HasFlag(CaseVariant.TICKET_WRONG_KVNO)) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Change the KVNO in the Ticket to an invalid Key Version Number (Int32.MaxValue)"); const int invalidKvno = System.Int32.MaxValue; serviceTicket.enc_part.kvno = new KerbInt32(invalidKvno); } #endregion #region Authenticator BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create Authenticator"); EncryptionKey subkey = KerberosUtility.GenerateKey(kerberosClient.Context.SessionKey); PrincipalName cname; if (variant.HasFlag(CaseVariant.AUTHENTICATOR_CNAME_NOT_MATCH)) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Use wrong cname in the Authenticator"); cname = new PrincipalName(new KerbInt32((long)PrincipalType.NT_PRINCIPAL), KerberosUtility.String2SeqKerbString(TestConfig.NonAdminUserName, TestConfig.DomainName)); } else { cname = kerberosClient.Context.CName.Name; } Authenticator authenticator = CreateAuthenticator(cname, crealm, subkey); if (variant.HasFlag(CaseVariant.AUTHENTICATOR_CREALM_NOT_MATCH)) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Use wrong crealm in the Authenticator"); authenticator.crealm = new Realm("kerb.com"); } if (variant.HasFlag(CaseVariant.AUTHENTICATOR_EXCEED_TIME_SKEW)) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Change the ctime in the Authenticator to one hour later"); DateTime oneHourLater = DateTime.Now.AddHours(1); string kerbTimeString = oneHourLater.ToUniversalTime().ToString("yyyyMMddhhmmssZ"); authenticator.ctime = new KerberosTime(kerbTimeString, true); } if (variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_AUTHENTICATOR)) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Add a type-unknown AuthorizationData to the Authenticator"); AuthorizationDataElement unknownElement = GenerateUnKnownAuthorizationDataElement(); authenticator.authorization_data = new AuthorizationData(new[] { unknownElement }); } if (variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_AUTHENTICATOR_OPTIONAL)) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Add a type-unknown AuthorizationData which is inside AD_IF_RELEVANT to the Authenticator"); AuthorizationDataElement unknownElement = GenerateUnKnownAuthorizationDataElement(); AD_IF_RELEVANT ifRelavantElement = new AD_IF_RELEVANT(new[] { unknownElement }); var dataBuffer = new Asn1BerEncodingBuffer(); ifRelavantElement.BerEncode(dataBuffer); AuthorizationDataElement unknownElementOptional = new AuthorizationDataElement(new KerbInt32((long)AuthorizationData_elementType.AD_IF_RELEVANT), new Asn1OctetString(dataBuffer.Data)); authenticator.authorization_data = new AuthorizationData(new[] { unknownElementOptional }); } #endregion #region AP Request BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create AP Request"); if (variant.HasFlag(CaseVariant.AUTHENTICATOR_WRONG_ENC_KEY)) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Use wrong key to encrypt the Authenticator"); kerberosClient.Context.Ticket.SessionKey = KerberosUtility.GenerateKey(kerberosClient.Context.Ticket.SessionKey); } KerberosApRequest request = new KerberosApRequest( kerberosClient.Context.Pvno, new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.MutualRequired)), kerberosClient.Context.Ticket, authenticator, KeyUsageNumber.AP_REQ_Authenticator ); #endregion BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create GSS Token"); byte[] token = KerberosUtility.AddGssApiTokenHeader(request, OidPkt, GssToken); Smb2FunctionalClientForKerbAuth smb2Client = new Smb2FunctionalClientForKerbAuth(TestConfig.Timeout, TestConfig, BaseTestSite); smb2Client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); #region Check the result byte[] repToken; uint status = DoSessionSetupWithGssToken(smb2Client, token, out repToken); if (variant.HasFlag(CaseVariant.AUTHENTICATOR_CNAME_NOT_MATCH) || variant.HasFlag(CaseVariant.AUTHENTICATOR_CREALM_NOT_MATCH)) { BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, status, "Session Setup should fail because the cname or crealm in the authenticator does not match the same field in the Ticket"); if (TestConfig.IsWindowsPlatform) { KerberosKrbError krbError = kerberosClient.GetKrbErrorFromToken(repToken); BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KRB_AP_ERR_BADMATCH, krbError.ErrorCode, "SMB Server should return {0}", KRB_ERROR_CODE.KRB_AP_ERR_BADMATCH); } smb2Client.Disconnect(); return; } if (variant.HasFlag(CaseVariant.AUTHENTICATOR_WRONG_ENC_KEY) || variant.HasFlag(CaseVariant.TICKET_WRONG_ENC_KEY)) { BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, status, "Session Setup should fail because Ticket or Authenticator cannot be correctly decrypted"); if (TestConfig.IsWindowsPlatform) { KerberosKrbError krbError = kerberosClient.GetKrbErrorFromToken(repToken); BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KRB_AP_ERR_MODIFIED, krbError.ErrorCode, "SMB Server should return {0}", KRB_ERROR_CODE.KRB_AP_ERR_MODIFIED); } smb2Client.Disconnect(); return; } if (variant.HasFlag(CaseVariant.AUTHENTICATOR_EXCEED_TIME_SKEW)) { BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, status, "Session Setup should fail because the server time and the client time " + "in the Authenticator differ by (1 hour) more than the allowable clock skew"); if (TestConfig.IsWindowsPlatform) { KerberosKrbError krbError = kerberosClient.GetKrbErrorFromToken(repToken); BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KRB_AP_ERR_SKEW, krbError.ErrorCode, "SMB Server should return {0}", KRB_ERROR_CODE.KRB_AP_ERR_SKEW); } smb2Client.Disconnect(); return; } if (variant.HasFlag(CaseVariant.TICKET_WRONG_KVNO) || variant.HasFlag(CaseVariant.TICKET_WRONG_REALM) || variant.HasFlag(CaseVariant.TICKET_WRONG_SNAME)) { BaseTestSite.Log.Add(LogEntryKind.Comment, "If decryption fails, server would try other keys"); } if (variant.HasFlag(CaseVariant.TICKET_NOT_VALID)) { BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, status, "Session Setup should fail because the starttime (tomorrow) in the Ticket " + "is later than the current time by more than the allowable clock skew"); if (TestConfig.IsWindowsPlatform) { KerberosKrbError krbError = kerberosClient.GetKrbErrorFromToken(repToken); BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KRB_AP_ERR_TKT_NYV, krbError.ErrorCode, "SMB Server should return {0}", KRB_ERROR_CODE.KRB_AP_ERR_TKT_NYV); } smb2Client.Disconnect(); return; } if (variant.HasFlag(CaseVariant.TICKET_EXPIRED)) { BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, status, "Session Setup should fail because the current time is later than the endtime (yesterday)" + " in the Ticket by more than the allowable clock skew"); if (TestConfig.IsWindowsPlatform) { KerberosKrbError krbError = kerberosClient.GetKrbErrorFromToken(repToken); BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KRB_AP_ERR_TKT_EXPIRED, krbError.ErrorCode, "SMB Server should return {0}", KRB_ERROR_CODE.KRB_AP_ERR_TKT_EXPIRED); } smb2Client.Disconnect(); return; } if (variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_TKT)) { BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, status, "Session Setup should fail because of the unknown AutherizationData in the ticket"); smb2Client.Disconnect(); return; } if (variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_AUTHENTICATOR)) { BaseTestSite.Log.Add(LogEntryKind.Comment, "Unknown AuthorizationData in the Authenticator should not fail the request"); } if (variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_TKT_OPTIONAL) || variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_AUTHENTICATOR_OPTIONAL)) { BaseTestSite.Log.Add(LogEntryKind.Comment, "Unknown AuthorizationData in AD_IF_RELEVANT is optional. " + "Server should not fail the request."); } KerberosApResponse apRep = kerberosClient.GetApResponseFromToken(repToken, GssToken); // Get subkey from AP response, which used for signing in smb2 apRep.Decrypt(kerberosClient.Context.Ticket.SessionKey.keyvalue.ByteArrayValue); smb2Client.SetSessionSigningAndEncryption(true, false, apRep.ApEncPart.subkey.keyvalue.ByteArrayValue); string path = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); AccessFile(smb2Client, path); #endregion smb2Client.LogOff(); smb2Client.Disconnect(); }
public void KerbAuth_Replay() { #region Get Service Ticket BaseTestSite.Log.Add(LogEntryKind.TestStep, "Initialize Kerberos Functional Client"); KerberosFunctionalClient kerberosClient = new KerberosFunctionalClient( TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword, KerberosAccountType.User, KDCIP, KDCPort, TransportType.TCP, OidPkt, BaseTestSite); //Create and send AS request const KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; kerberosClient.SendAsRequest(options, null); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client expects Kerberos Error from KDC"); //Receive preauthentication required error METHOD_DATA methodData; KerberosKrbError krbError = kerberosClient.ExpectPreauthRequiredError(out methodData); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client sends AS request with PA-DATA set"); //Create sequence of PA data string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp, 0, kerberosClient.Context.SelectedEType, kerberosClient.Context.CName.Password, kerberosClient.Context.CName.Salt); PaPacRequest paPacRequest = new PaPacRequest(true); Asn1SequenceOf <PA_DATA> seqOfPaData = new Asn1SequenceOf <PA_DATA>(new[] { paEncTimeStamp.Data, paPacRequest.Data }); //Create and send AS request kerberosClient.SendAsRequest(options, seqOfPaData); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client expects AS response from KDC"); KerberosAsResponse asResponse = kerberosClient.ExpectAsResponse(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create and send TGS request BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client sends TGS request to KDC"); kerberosClient.SendTgsRequest(servicePrincipalName, options); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Kerberos Functional Client expects TGS response from KDC"); KerberosTgsResponse tgsResponse = kerberosClient.ExpectTgsResponse(); BaseTestSite.Assert.AreEqual(servicePrincipalName, KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname), "Service principal name in service ticket should match expected."); #endregion #region Create AP request Ticket serviceTicket = kerberosClient.Context.Ticket.Ticket; Realm crealm = serviceTicket.realm; EncryptionKey subkey = KerberosUtility.GenerateKey(kerberosClient.Context.SessionKey); PrincipalName cname = kerberosClient.Context.CName.Name; Authenticator authenticator = CreateAuthenticator(cname, crealm, subkey); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create AP Request"); KerberosApRequest request = new KerberosApRequest( kerberosClient.Context.Pvno, new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.MutualRequired)), kerberosClient.Context.Ticket, authenticator, KeyUsageNumber.AP_REQ_Authenticator ); #endregion #region Create GSS token and send session setup request BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create GSS Token"); byte[] token = KerberosUtility.AddGssApiTokenHeader(request, OidPkt, GssToken); Smb2FunctionalClientForKerbAuth smb2Client = new Smb2FunctionalClientForKerbAuth(TestConfig.Timeout, TestConfig, BaseTestSite); smb2Client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); byte[] repToken; uint status = DoSessionSetupWithGssToken(smb2Client, token, out repToken); KerberosApResponse apRep = kerberosClient.GetApResponseFromToken(repToken, GssToken); // Get subkey from AP response, which used for signing in smb2 apRep.Decrypt(kerberosClient.Context.Ticket.SessionKey.keyvalue.ByteArrayValue); smb2Client.SetSessionSigningAndEncryption(true, false, apRep.ApEncPart.subkey.keyvalue.ByteArrayValue); #endregion #region Second client BaseTestSite.Log.Add(LogEntryKind.TestStep, "Replay the request from another client"); Smb2FunctionalClientForKerbAuth smb2Client2 = new Smb2FunctionalClientForKerbAuth(TestConfig.Timeout, TestConfig, BaseTestSite); smb2Client2.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress); status = DoSessionSetupWithGssToken(smb2Client2, token, out repToken); BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, status, "Session Setup should fail because it uses a Replay of KRB_AP_REQ"); if (TestConfig.IsWindowsPlatform) { krbError = kerberosClient.GetKrbErrorFromToken(repToken); BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KRB_AP_ERR_REPEAT, krbError.ErrorCode, "SMB Server should return {0}", KRB_ERROR_CODE.KRB_AP_ERR_REPEAT); } smb2Client2.Disconnect(); #endregion string path = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare); AccessFile(smb2Client, path); smb2Client.LogOff(); smb2Client.Disconnect(); }
/// <summary> /// Convert uint to Asn.1 formatted ContextFlags /// </summary> /// <param name="attributes">Security context attributes</param> /// <returns>the converted ContextFlags</returns> public static ContextFlags ConvertUintToContextFlags(uint attributes) { ContextFlags options = new ContextFlags(KerberosUtility.ConvertInt2Flags((int)attributes)); return(options); }
public KileTgsResponse CreateTgsResponse( KileConnection kileConnection, Asn1SequenceOf <PA_DATA> seqOfPaData, EncTicketFlags encTicketFlags, EncryptionKey ticketEncryptKey, AuthorizationData ticketAuthorizationData) { KileServerContext serverContext = GetServerContextByKileConnection(kileConnection); if (ticketEncryptKey == null) { throw new ArgumentNullException(nameof(ticketEncryptKey)); } else { serverContext.TicketEncryptKey = ticketEncryptKey; } var response = new KileTgsResponse(serverContext); // Construct a Ticket var ticket = new Ticket(); ticket.tkt_vno = new Asn1Integer(ConstValue.KERBEROSV5); ticket.realm = new Realm(domain); ticket.sname = serverContext.SName; // Set EncTicketPart var encTicketPart = new EncTicketPart(); EncryptionType encryptionType = (EncryptionType)serverContext.EncryptType.Elements[0].Value; encTicketPart.key = new EncryptionKey(new KerbInt32((int)encryptionType), new Asn1OctetString(GetEncryptionKeyByType(encryptionType))); encTicketPart.flags = new TicketFlags(KerberosUtility.ConvertInt2Flags((int)encTicketFlags)); encTicketPart.crealm = serverContext.TgsTicket.crealm; encTicketPart.cname = serverContext.TgsTicket.cname; encTicketPart.transited = serverContext.TgsTicket.transited; encTicketPart.authtime = KerberosUtility.CurrentKerberosTime; encTicketPart.starttime = KerberosUtility.CurrentKerberosTime; encTicketPart.endtime = serverContext.TgsTicket.endtime; encTicketPart.renew_till = serverContext.TgsTicket.renew_till; encTicketPart.caddr = serverContext.Addresses; encTicketPart.authorization_data = ticketAuthorizationData; response.TicketEncPart = encTicketPart; // Set AS_REP response.Response.pvno = new Asn1Integer(ConstValue.KERBEROSV5); response.Response.msg_type = new Asn1Integer((int)MsgType.KRB_TGS_RESP); response.Response.padata = seqOfPaData; response.Response.crealm = serverContext.UserRealm; response.Response.cname = serverContext.UserName; response.Response.ticket = ticket; // Set EncASRepPart var encTGSRepPart = new EncTGSRepPart(); encTGSRepPart.key = encTicketPart.key; var element = new LastReqElement(new KerbInt32(0), KerberosUtility.CurrentKerberosTime); encTGSRepPart.last_req = new LastReq(new LastReqElement[] { element }); encTGSRepPart.nonce = serverContext.Nonce; encTGSRepPart.flags = encTicketPart.flags; encTGSRepPart.authtime = encTicketPart.authtime; encTGSRepPart.starttime = encTicketPart.starttime; encTGSRepPart.endtime = encTicketPart.endtime; encTGSRepPart.renew_till = encTicketPart.renew_till; encTGSRepPart.srealm = ticket.realm; encTGSRepPart.sname = ticket.sname; encTGSRepPart.caddr = encTicketPart.caddr; response.EncPart = encTGSRepPart; return(response); }
public void NetworkLogonLdapWithoutPac_Ldap() { base.Logging(); client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[1].Username, this.testConfig.LocalRealm.User[1].Password, KerberosAccountType.User, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid); // Kerberos Proxy Service is used if (this.testConfig.UseProxy) { BaseTestSite.Log.Add(LogEntryKind.Comment, "Initialize KKDCP Client ."); KKDCPClient proxyClient = new KKDCPClient(proxyClientConfig); proxyClient.TargetDomain = this.testConfig.LocalRealm.RealmName; client.UseProxy = true; client.ProxyClient = proxyClient; } //Create and send AS request KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); //Recieve preauthentication required error METHOD_DATA methodData; KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData); //Create sequence of PA data string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp, 0, this.client.Context.SelectedEType, this.client.Context.CName.Password, this.client.Context.CName.Salt); PaPacRequest paPacRequest = new PaPacRequest(false); Asn1SequenceOf <PA_DATA> seqOfPaData = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data }); //Create and send AS request client.SendAsRequest(options, seqOfPaData); KerberosAsResponse asResponse = client.ExpectAsResponse(); BaseTestSite.Assert.IsNotNull(asResponse.Response.ticket, "AS response should contain a TGT."); //Create and send TGS request client.SendTgsRequest(this.testConfig.LocalRealm.LdapServer[0].LdapServiceName, options); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); AuthorizationData data = null; EncryptionKey subkey = KerberosUtility.GenerateKey(client.Context.SessionKey); byte[] token = client.CreateGssApiToken(ApOptions.MutualRequired, data, subkey, ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG, this.testConfig.LocalRealm.LdapServer[0].GssToken); //AP exchange part byte[] repToken = this.SendAndRecieveLdapAp(this.testConfig.LocalRealm.LdapServer[0], token, this.testConfig.TrustedRealm.LdapServer[0].GssToken); KerberosApResponse apResponse = client.GetApResponseFromToken(repToken, this.testConfig.LocalRealm.LdapServer[0].GssToken); }