public byte[] ToBytes(TransportType transportType) { Asn1BerEncodingBuffer asBerBuffer = new Asn1BerEncodingBuffer(); this.FastReq.BerEncode(asBerBuffer, true); if (transportType == TransportType.TCP) { return KerberosUtility.WrapLength(asBerBuffer.Data, true); } else { return asBerBuffer.Data; } }
/// <summary> /// Create an instance. /// </summary> public KpasswordRequest(KerberosTicket ticket, Authenticator authenticator, string newPwd, bool isAuthErrorRequired = false) { //Create KerberosApRequest long pvno = KerberosConstValue.KERBEROSV5; APOptions option = new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.None)); KerberosApRequest ap_req = new KerberosApRequest(pvno, option, ticket, authenticator, KeyUsageNumber.AP_REQ_Authenticator); //Create KRB_PRIV ChangePasswdData pwd_data = new ChangePasswdData(new Asn1OctetString(newPwd), null, null); priv_enc_part = new EncKrbPrivPart(); priv_enc_part.user_data = pwd_data.newpasswd; priv_enc_part.usec = authenticator.cusec; priv_enc_part.seq_number = authenticator.seq_number; priv_enc_part.s_address = new HostAddress(new KerbInt32((int)AddressType.NetBios), new Asn1OctetString(Encoding.ASCII.GetBytes(System.Net.Dns.GetHostName()))); Asn1BerEncodingBuffer asnBuffPriv = new Asn1BerEncodingBuffer(); priv_enc_part.BerEncode(asnBuffPriv, true); byte[] encAsnEncodedPriv = null; if (!isAuthErrorRequired) { encAsnEncodedPriv = KerberosUtility.Encrypt((EncryptionType)authenticator.subkey.keytype.Value, authenticator.subkey.keyvalue.ByteArrayValue, asnBuffPriv.Data, (int)KeyUsageNumber.KRB_PRIV_EncPart); } else { encAsnEncodedPriv = KerberosUtility.Encrypt((EncryptionType)authenticator.subkey.keytype.Value, authenticator.subkey.keyvalue.ByteArrayValue, asnBuffPriv.Data, (int)KeyUsageNumber.None); } var encrypted = new EncryptedData(); encrypted.etype = new KerbInt32(authenticator.subkey.keytype.Value); encrypted.cipher = new Asn1OctetString(encAsnEncodedPriv); KRB_PRIV krb_priv = new KRB_PRIV(new Asn1Integer(pvno), new Asn1Integer((long)MsgType.KRB_PRIV), encrypted); //Calculate the msg_length and ap_req_length krb_priv.BerEncode(privBuffer, true); ap_req.Request.BerEncode(apBuffer, true); version = 0x0001; ap_req_length = (ushort)apBuffer.Data.Length; msg_length = (ushort)(ap_req_length + privBuffer.Data.Length + 3 * sizeof(ushort)); //Convert Endian version = KerberosUtility.ConvertEndian(version); ap_req_length = KerberosUtility.ConvertEndian(ap_req_length); msg_length = KerberosUtility.ConvertEndian(msg_length); }
/// <summary> /// Encode this class into byte array. /// </summary> /// <returns>The byte array of the class.</returns> public override byte[] ToBytes() { Asn1BerEncodingBuffer asBerBuffer = new Asn1BerEncodingBuffer(); this.Request.BerEncode(asBerBuffer, true); KerberosUtility.OnDumpMessage("KRB5:KrbMessage", "Kerberos Message", KerberosUtility.DumpLevel.WholeMessage, asBerBuffer.Data); if (transportType == TransportType.TCP) { return KerberosUtility.WrapLength(asBerBuffer.Data, true); } else { return asBerBuffer.Data; } }
/// <summary> /// Create an instance. /// </summary> public KerberosApRequest(long pvno, APOptions ap_options, KerberosTicket ticket, Authenticator authenticator, KeyUsageNumber keyUsageNumber) { Asn1BerEncodingBuffer asnBuffPlainAuthenticator = new Asn1BerEncodingBuffer(); authenticator.BerEncode(asnBuffPlainAuthenticator, true); KerberosUtility.OnDumpMessage("KRB5:Authenticator", "Authenticator in AP-REQ structure", KerberosUtility.DumpLevel.PartialMessage, asnBuffPlainAuthenticator.Data); byte[] encAsnEncodedAuth = KerberosUtility.Encrypt((EncryptionType)ticket.SessionKey.keytype.Value, ticket.SessionKey.keyvalue.ByteArrayValue, asnBuffPlainAuthenticator.Data, (int)keyUsageNumber); var encrypted = new EncryptedData(); encrypted.etype = new KerbInt32(ticket.SessionKey.keytype.Value); encrypted.cipher = new Asn1OctetString(encAsnEncodedAuth); long msg_type = (long)MsgType.KRB_AP_REQ; Request = new AP_REQ(new Asn1Integer(pvno), new Asn1Integer(msg_type), ap_options, ticket.Ticket, encrypted); Authenticator = authenticator; }
/// <summary> /// Create and send TGS request /// </summary> /// <param name="sName">Service principal name</param> /// <param name="kdcOptions">KDC options</param> /// <param name="seqPadata">A sequence of preauthentication data</param> /// <param name="checksumType">Checksum type of PA-TGS-REQ</param> /// <param name="additionalTicket">Additional ticket</param> /// <param name="data">Authorization data</param> public void SendTgsRequest(string sName, KdcOptions kdcOptions, Asn1SequenceOf<PA_DATA> seqPadata = null, Ticket additionalTicket = null, AuthorizationData dataInAuthenticator = null, AuthorizationData dataInEncAuthData = null) { if (sName == null) { throw new ArgumentNullException("sName"); } PrincipalName sname = new PrincipalName( new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName.Split('/'))); KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname, dataInEncAuthData); Asn1BerEncodingBuffer bodyBuffer = new Asn1BerEncodingBuffer(); kdcReqBody.BerEncode(bodyBuffer); ChecksumType checksumType = KerberosUtility.GetChecksumType(Context.SelectedEType); PA_DATA paTgsReq = CreatePaTgsReq(checksumType, bodyBuffer.Data, dataInAuthenticator); Asn1SequenceOf<PA_DATA> tempPaData = null; if (seqPadata == null || seqPadata.Elements == null || seqPadata.Elements.Length == 0) { tempPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paTgsReq }); } else { PA_DATA[] paDatas = new PA_DATA[seqPadata.Elements.Length + 1]; Array.Copy(seqPadata.Elements, paDatas, seqPadata.Elements.Length); paDatas[seqPadata.Elements.Length] = paTgsReq; tempPaData = new Asn1SequenceOf<PA_DATA>(paDatas); } KerberosTgsRequest tgsRequest = new KerberosTgsRequest(KerberosConstValue.KERBEROSV5, kdcReqBody, tempPaData, Context.TransportType); this.SendPdu(tgsRequest); this.testSite.Log.Add(LogEntryKind.Debug, "Send TGS request."); }
public PaFxFastReq CreateAsPaFxFast( EncryptionKey subKey, FastOptions fastOptions, ApOptions apOptions, Asn1SequenceOf<PA_DATA> seqPaData, string sName, KDC_REQ_BODY kdcReqBody, KrbFastArmorType armorType ) { string domain = this.Context.Realm.Value; PrincipalName sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName, domain)); var armorKey = KerberosUtility.MakeArmorKey( Context.SelectedEType, subKey.keyvalue.ByteArrayValue, Context.ArmorSessionKey.keyvalue.ByteArrayValue); Context.FastArmorkey = new EncryptionKey(new KerbInt32((long)Context.SelectedEType), new Asn1OctetString(armorKey)); Asn1BerEncodingBuffer encodebuf = new Asn1BerEncodingBuffer(); kdcReqBody.BerEncode(encodebuf); var checksumType = KerberosUtility.GetChecksumType(Context.SelectedEType); var chksum = KerberosUtility.GetChecksum( armorKey, encodebuf.Data, (int)KeyUsageNumber.FAST_REQ_CHECKSUM, checksumType); Checksum checkSum = new Checksum(new KerbInt32((int)checksumType), new Asn1OctetString(chksum)); Authenticator plaintextAuthenticator = CreateAuthenticator(Context.ArmorTicket, null, subKey); KerberosApRequest apReq = new KerberosApRequest(Context.Pvno, new APOptions(KerberosUtility.ConvertInt2Flags((int)apOptions)), Context.ArmorTicket, plaintextAuthenticator, KeyUsageNumber.AP_REQ_Authenticator); KDC_REQ_BODY innerKdcReqBody = CreateKdcRequestBody(KdcOptions.CANONICALIZE | KdcOptions.FORWARDABLE | KdcOptions.RENEWABLE, sname); KerberosFastRequest fastReq = new KerberosFastRequest(fastOptions, seqPaData, innerKdcReqBody); FastArmorApRequest fastArmor = new FastArmorApRequest(apReq.Request); fastArmor.armorType = armorType; KerberosArmoredRequest armoredReq = new KerberosArmoredRequest(fastArmor, checkSum, (long)Context.SelectedEType, armorKey, fastReq); PA_FX_FAST_REQUEST paFxFastReq = new PA_FX_FAST_REQUEST(); paFxFastReq.SetData(PA_FX_FAST_REQUEST.armored_data, armoredReq.FastArmoredReq); PaFxFastReq paFxfast = new PaFxFastReq(paFxFastReq); return paFxfast; }
private KDC_REQ_BODY CreateKdcRequestBody( KdcOptions kdcOptions, PrincipalName sName, AuthorizationData data = null ) { KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sName); if (data == null) return kdcReqBody; Asn1BerEncodingBuffer asnBuffer = new Asn1BerEncodingBuffer(); // Fix me: NullReferenceException if data is null. if (data != null) data.BerEncode(asnBuffer, true); EncryptedData eData = new EncryptedData(); eData.etype = new KerbInt32(0); byte[] encAsnEncoded = asnBuffer.Data; if (Context.SessionKey != null && Context.SessionKey.keytype != null && Context.SessionKey.keyvalue != null && Context.SessionKey.keyvalue.Value != null) { encAsnEncoded = KerberosUtility.Encrypt((EncryptionType)Context.SessionKey.keytype.Value, Context.SessionKey.keyvalue.ByteArrayValue, asnBuffer.Data, (int)KeyUsageNumber.TGS_REQ_KDC_REQ_BODY_AuthorizationData); eData.etype = new KerbInt32(Context.SessionKey.keytype.Value); } eData.cipher = new Asn1OctetString(encAsnEncoded); kdcReqBody.enc_authorization_data = eData; return kdcReqBody; }
public PaEncryptedChallenge(EncryptionType type, string timeStamp, int usec, EncryptionKey armorKey, EncryptionKey userLongTermKey) { this.TimeStamp = timeStamp; this.Usec = usec; var keyvalue = KeyGenerator.KrbFxCf2( (EncryptionType)armorKey.keytype.Value, armorKey.keyvalue.ByteArrayValue, userLongTermKey.keyvalue.ByteArrayValue, "clientchallengearmor", "challengelongterm"); switch (type) { case EncryptionType.AES256_CTS_HMAC_SHA1_96: { var key = new EncryptionKey(new KerbInt32((long)EncryptionType.AES256_CTS_HMAC_SHA1_96), new Asn1OctetString(keyvalue)); this.Key = key; break; } case EncryptionType.RC4_HMAC: { var key = new EncryptionKey(new KerbInt32((long)EncryptionType.RC4_HMAC), new Asn1OctetString(keyvalue)); this.Key = key; break; } default: throw new ArgumentException("Unsupported encryption type."); } // create a timestamp PA_ENC_TS_ENC paEncTsEnc = new PA_ENC_TS_ENC(new KerberosTime(this.TimeStamp), new Microseconds(this.Usec)); Asn1BerEncodingBuffer currTimeStampBuffer = new Asn1BerEncodingBuffer(); paEncTsEnc.BerEncode(currTimeStampBuffer); var rawData = currTimeStampBuffer.Data; KerberosUtility.OnDumpMessage("KRB5:PA-ENC-TS-ENC", "Encrypted Timestamp Pre-authentication", KerberosUtility.DumpLevel.PartialMessage, rawData); // encrypt the timestamp byte[] encTimeStamp = KerberosUtility.Encrypt((EncryptionType)this.Key.keytype.Value, this.Key.keyvalue.ByteArrayValue, rawData, (int)KeyUsageNumber.ENC_CHALLENGE_CLIENT); EncryptedChallenge encryptedChallenge = new EncryptedChallenge(new KerbInt32((long)this.Key.keytype.Value), null, new Asn1OctetString(encTimeStamp)); Asn1BerEncodingBuffer paEncTimestampBuffer = new Asn1BerEncodingBuffer(); encryptedChallenge.BerEncode(paEncTimestampBuffer, true); Data = new PA_DATA(new KerbInt32((long)PaDataType.PA_ENCRYPTED_CHALLENGE), new Asn1OctetString(paEncTimestampBuffer.Data)); }
public void KrbErrorTktNotYetValid() { 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, 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 client.SendTgsRequest(this.testConfig.LocalRealm.FileServer[0].Smb2ServiceName, options); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); // Change ticket EncryptionKey tgskey = testConfig.QueryKey( this.testConfig.LocalRealm.FileServer[0].Smb2ServiceName, this.testConfig.LocalRealm.RealmName, this.client.Context.SelectedEType); // Decrypt ticket tgsResponse.DecryptTicket(tgskey); // Set ticket start time 15 minutes later than now string nyvTime = DateTime.Now.AddMinutes(15).ToUniversalTime().ToString("yyyyMMddHHmmss") + "Z"; tgsResponse.TicketEncPart.starttime = new KerberosTime(nyvTime); Asn1BerEncodingBuffer encodeBuffer = new Asn1BerEncodingBuffer(); tgsResponse.TicketEncPart.BerEncode(encodeBuffer, true); EncryptionType encryptType = (EncryptionType) tgsResponse.Response.ticket.enc_part.etype.Value; var key = KeyGenerator.MakeKey(encryptType, this.testConfig.LocalRealm.FileServer[0].Password, this.testConfig.LocalRealm.FileServer[0].ServiceSalt); // Re-encrypt ticket var encrypedData = KerberosUtility.Encrypt( encryptType, key, encodeBuffer.Data, (int)KeyUsageNumber.AS_REP_TicketAndTGS_REP_Ticket); tgsResponse.Response.ticket.enc_part = new EncryptedData(new KerbInt32((long)encryptType), null, new Asn1OctetString(encrypedData)); 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, "Create and send Smb2 request."); KerberosKrbError error = client.GetKrbErrorFromToken(SendAndRecieveSmb2Ap(this.testConfig.LocalRealm.FileServer[0], token)); BaseTestSite.Log.Add(LogEntryKind.Comment, "Recieve Kerberos error."); BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KRB_AP_ERR_TKT_NYV, error.ErrorCode, "If the starttime is later than the current time by more than the allowable clock skew (10 minutes), " + "the KRB_AP_ERR_TKT_NYV error is returned."); }
public void KrbFastFinishedTgsRep() { base.Logging(); client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.ClientComputer.NetBiosName, this.testConfig.LocalRealm.ClientComputer.Password, KerberosAccountType.Device, testConfig.LocalRealm.KDC[0].IPAddress, testConfig.LocalRealm.KDC[0].Port, testConfig.TransportType, testConfig.SupportedOid, testConfig.LocalRealm.ClientComputer.AccountSalt); // 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; } // AS_REQ and KRB-ERROR using device principal KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE; client.SendAsRequest(options, null); METHOD_DATA methodData; KerberosKrbError krbError1 = client.ExpectPreauthRequiredError(out methodData); // AS_REQ and AS_REP using device principal string timeStamp = KerberosUtility.CurrentKerberosTime.Value; PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp( timeStamp, 0, client.Context.SelectedEType, this.client.Context.CName.Password, this.client.Context.CName.Salt); Asn1SequenceOf<PA_DATA> seqOfPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data }); client.SendAsRequest(options, seqOfPaData); KerberosAsResponse asResponse = client.ExpectAsResponse(); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("The type of AS-REP encrypted part is {0}.", asResponse.EncPart.GetType().Name)); // Switch to user principal client = new KerberosTestClient( this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.User[1].Username, this.testConfig.LocalRealm.User[1].Password, KerberosAccountType.User, client.Context.Ticket, client.Context.SessionKey, 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; } // FAST armored AS_REQ and KRB-ERROR using user principal //Create a "random" key. var subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password02!", "this is a salt"); var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions(KerberosUtility.ConvertInt2Flags((int)0)); var apOptions = ApOptions.None; Asn1SequenceOf<PA_DATA> seqOfPaData2 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { new PA_DATA(new KerbInt32((long)PaDataType.PA_FX_FAST), null) }); client.SendAsRequestWithFast(options, seqOfPaData2, null, subkey, fastOptions, apOptions); KerberosKrbError krbError2 = client.ExpectKrbError(); BaseTestSite.Assert.AreEqual(krbError2.ErrorCode, KRB_ERROR_CODE.KDC_ERR_PREAUTH_REQUIRED, "Pre-authentication required."); // FAST armored AS_REQ and AS_REP using user principal var userKey = KerberosUtility.MakeKey( client.Context.SelectedEType, client.Context.CName.Password, client.Context.CName.Salt); PaEncryptedChallenge paEncTimeStamp3 = new PaEncryptedChallenge( client.Context.SelectedEType, KerberosUtility.CurrentKerberosTime.Value, 0, client.Context.FastArmorkey, userKey); Asn1SequenceOf<PA_DATA> seqOfPaData3 = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paEncTimeStamp3.Data }); client.SendAsRequestWithFast(options, seqOfPaData3, null, subkey, fastOptions, apOptions); KerberosAsResponse userKrbAsRep = client.ExpectAsResponse(); BaseTestSite.Log.Add( LogEntryKind.Comment, string.Format("The type of AS-REP encrypted part is {0}.", userKrbAsRep.EncPart.GetType().Name)); // FAST armored TGS_REQ and TGS_REP using user principal subkey = KerberosUtility.MakeKey(client.Context.SelectedEType, "Password03!", "this is a salt"); client.SendTgsRequestWithFast(testConfig.LocalRealm.ClientComputer.DefaultServiceName, options, null, null, subkey, fastOptions, apOptions); KerberosTgsResponse userKrbTgsRep = client.ExpectTgsResponse(KeyUsageNumber.TGS_REP_encrypted_part_subkey); BaseTestSite.Assert.IsNotNull(userKrbTgsRep.EncPart, "The encrypted part of TGS-REP is decrypted."); //Verify KrbFastFinished. KrbFastFinished fastFinishedTgs = null; BaseTestSite.Assert.IsNotNull(userKrbAsRep.Response.padata, "The padata of AS-REP is not null."); BaseTestSite.Assert.IsNotNull(userKrbAsRep.Response.padata.Elements, "The padata of AS-REP is not empty."); foreach (PA_DATA paData in userKrbTgsRep.Response.padata.Elements) { var parsedPaData = PaDataParser.ParseRepPaData(paData); if (parsedPaData is PaFxFastRep) { var armoredRep = ((PaFxFastRep)parsedPaData).GetArmoredRep(); var kerbFastRep = ((PaFxFastRep)parsedPaData).GetKerberosFastRep(client.Context.FastArmorkey); fastFinishedTgs = kerbFastRep.FastResponse.finished; break; } } BaseTestSite.Assert.IsNotNull(fastFinishedTgs, "The finished field contains a KrbFastFinished structure."); Asn1BerEncodingBuffer buf2 = new Asn1BerEncodingBuffer(); userKrbTgsRep.Response.ticket.BerEncode(buf2); Checksum ticketChecksumTgs = new Checksum(new KerbInt32((long)KerberosUtility.GetChecksumType(client.Context.SelectedEType)), new Asn1OctetString(KerberosUtility.GetChecksum( client.Context.FastArmorkey.keyvalue.ByteArrayValue, buf2.Data, (int)KeyUsageNumber.FAST_FINISHED, KerberosUtility.GetChecksumType(client.Context.SelectedEType)))); BaseTestSite.Assert.IsTrue( KerberosUtility.CompareChecksum(fastFinishedTgs.ticket_checksum, ticketChecksumTgs), "The ticket checksum is correct."); }
/// <summary> /// Encode this class into byte array. /// </summary> /// <returns>The byte array of the class.</returns> public byte[] ToBytes() { Asn1BerEncodingBuffer asBerBuffer = new Asn1BerEncodingBuffer(); this.Message.BerEncode(asBerBuffer, true); return asBerBuffer.Data; }
/// <summary> /// Encode this structure into byte array. /// </summary> /// <returns>The byte array of the structure.</returns> public override byte[] ToBytes() { List<byte> totalBuffer = new List<byte>(); RdpbcgrEncoder.EncodeStructure(totalBuffer, tpktHeader); RdpbcgrEncoder.EncodeStructure(totalBuffer, x224Data); if (mcsCrsp != null) { byte[] gccData = EncodeGccRspData(mcsCrsp.gccPdu); #region Filling MCS Connect Response PDU Connect_Response connectResponse = new Connect_Response(); connectResponse.result = new Result(mcsCrsp.result); connectResponse.calledConnectId = new Asn1Integer(mcsCrsp.calledConnectId); connectResponse.domainParameters = new DomainParameters(new Asn1Integer(mcsCrsp.domainParameters.maxChannelIds), new Asn1Integer(mcsCrsp.domainParameters.maxUserIds), new Asn1Integer(mcsCrsp.domainParameters.maxTokenIds), new Asn1Integer(mcsCrsp.domainParameters.numPriorities), new Asn1Integer(mcsCrsp.domainParameters.minThroughput), new Asn1Integer(mcsCrsp.domainParameters.maxHeight), new Asn1Integer(mcsCrsp.domainParameters.maxMcsPduSize), new Asn1Integer(mcsCrsp.domainParameters.protocolVersion)); connectResponse.userData = new Asn1OctetString(gccData); #endregion Filling MCS Connect Response PDU #region Encode MCS Connect Initial PDU Asn1BerEncodingBuffer berEncodeBuffer = new Asn1BerEncodingBuffer(); connectResponse.BerEncode(berEncodeBuffer); #endregion MCS Connect Initial PDU RdpbcgrEncoder.EncodeBytes(totalBuffer, berEncodeBuffer.Data); } byte[] encodedBytes = RdpbcgrUtility.ToBytes(totalBuffer); // ToDo: Ugly dump message code here // ETW Provider Dump Code RdpbcgrUtility.ETWProviderDump(this.GetType().Name, encodedBytes); return encodedBytes; }
/// <summary> /// Encode this structure into byte array. /// </summary> /// <returns>The byte array of the structure.</returns> public override byte[] ToBytes() { List<byte> totalBuffer = new List<byte>(); RdpbcgrEncoder.EncodeStructure(totalBuffer, tpktHeader); RdpbcgrEncoder.EncodeStructure(totalBuffer, x224Data); if (mcsCi != null) { byte[] gccData = EncodeGccData(mcsCi.gccPdu); #region Filling MCS Connect Initial PDU Connect_Initial connectInitial = new Connect_Initial(); connectInitial.calledDomainSelector = new Asn1OctetString(mcsCi.calledDomainSelector); connectInitial.callingDomainSelector = new Asn1OctetString(mcsCi.callingDomainSelector); connectInitial.upwardFlag = new Asn1Boolean(mcsCi.upwardFlag); connectInitial.targetParameters = new DomainParameters(new Asn1Integer(mcsCi.targetParameters.maxChannelIds), new Asn1Integer(mcsCi.targetParameters.maxUserIds), new Asn1Integer(mcsCi.targetParameters.maxTokenIds), new Asn1Integer(mcsCi.targetParameters.numPriorities), new Asn1Integer(mcsCi.targetParameters.minThroughput), new Asn1Integer(mcsCi.targetParameters.maxHeight), new Asn1Integer(mcsCi.targetParameters.maxMcsPduSize), new Asn1Integer(mcsCi.targetParameters.protocolVersion)); connectInitial.minimumParameters = new DomainParameters(new Asn1Integer(mcsCi.minimumParameters.maxChannelIds), new Asn1Integer(mcsCi.minimumParameters.maxUserIds), new Asn1Integer(mcsCi.minimumParameters.maxTokenIds), new Asn1Integer(mcsCi.minimumParameters.numPriorities), new Asn1Integer(mcsCi.minimumParameters.minThroughput), new Asn1Integer(mcsCi.minimumParameters.maxHeight), new Asn1Integer(mcsCi.minimumParameters.maxMcsPduSize), new Asn1Integer(mcsCi.minimumParameters.protocolVersion)); connectInitial.maximumParameters = new DomainParameters(new Asn1Integer(mcsCi.maximumParameters.maxChannelIds), new Asn1Integer(mcsCi.maximumParameters.maxUserIds), new Asn1Integer(mcsCi.maximumParameters.maxTokenIds), new Asn1Integer(mcsCi.maximumParameters.numPriorities), new Asn1Integer(mcsCi.maximumParameters.minThroughput), new Asn1Integer(mcsCi.maximumParameters.maxHeight), new Asn1Integer(mcsCi.maximumParameters.maxMcsPduSize), new Asn1Integer(mcsCi.maximumParameters.protocolVersion)); connectInitial.userData = new Asn1OctetString(gccData); #endregion Filling MCS Connect Initial PDU #region Encode MCS Connect Initial PDU Asn1BerEncodingBuffer berEncodeBuffer = new Asn1BerEncodingBuffer(); connectInitial.BerEncode(berEncodeBuffer); #endregion MCS Connect Initial PDU if (berEncodeBuffer.Data != null) { RdpbcgrEncoder.EncodeBytes(totalBuffer, berEncodeBuffer.Data); } } return RdpbcgrUtility.ToBytes(totalBuffer); }
public void DetectTicketModification_Http() { 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, 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(this.testConfig.LocalRealm.WebServer[0].HttpServiceName, options); KerberosTgsResponse tgsResponse = client.ExpectTgsResponse(); EncryptionKey tgskey = testConfig.QueryKey(this.testConfig.LocalRealm.WebServer[0].HttpServiceName, this.testConfig.LocalRealm.RealmName, this.client.Context.SelectedEType); tgsResponse.DecryptTicket(tgskey); //Change ticket //tgsResponse.DecryptTicket(this.testConfig.LocalRealm.WebServer[0].Password, this.testConfig.LocalRealm.WebServer[0].ServiceSalt); //tgsResponse.TicketEncPart.cname = new PrincipalName((long)PrincipalType.NT_PRINCIPAL, KerberosUtility.String2SeqKerbString("NonExistUser", testConfig.LocalRealm.RealmName)); Asn1BerEncodingBuffer encodeBuffer = new Asn1BerEncodingBuffer(); tgsResponse.TicketEncPart.BerEncode(encodeBuffer, true); EncryptionType encryptType = (EncryptionType)tgsResponse.Response.ticket.enc_part.etype.Value; var key = KeyGenerator.MakeKey(encryptType, "WrongPassword", this.testConfig.LocalRealm.WebServer[0].ServiceSalt); var encrypedData = KerberosUtility.Encrypt( encryptType, key, encodeBuffer.Data, (int)KeyUsageNumber.AS_REP_TicketAndTGS_REP_Ticket); tgsResponse.Response.ticket.enc_part = new EncryptedData(new KerbInt32((long)encryptType), null, new Asn1OctetString(encrypedData)); 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, "Create and send Http request."); //Receive Error here KerberosKrbError error = client.GetKrbErrorFromToken(SendAndRecieveHttpAp(this.testConfig.LocalRealm.WebServer[0], token)); BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KRB_AP_ERR_MODIFIED, error.ErrorCode, "AP should return KRB_AP_ERR_MODIFIED if authenticator changed"); }
/// <summary> /// Converts the packet to a byte array that transmits on the wire. /// </summary> /// <returns>The byte array.</returns> public override byte[] ToBytes() { Asn1BerEncodingBuffer berEncoder = new Asn1BerEncodingBuffer(); LdapV2.LDAPMessage ldapv2Msg = ldapMessagev2 as LdapV2.LDAPMessage; if (ldapv2Msg != null) { ldapv2Msg.BerEncode(berEncoder); return berEncoder.Data; } LdapV3.LDAPMessage ldapv3Msg = ldapMessagev3 as LdapV3.LDAPMessage; if (ldapv3Msg != null) { ldapv3Msg.BerEncode(berEncoder); return berEncoder.Data; } throw new StackException("The LDAP v2 and v3 messages cannot be both null"); }
/// <summary> /// Create and send FAST TGS request /// </summary> /// <param name="sName">Service principal name</param> /// <param name="kdcOptions">KDC options</param> /// <param name="innerSeqPaData">A sequence of preauthentication data in FAST request</param> /// <param name="outerSeqPaData">A sequence of preauthentication data</param> /// <param name="subKey">Sub-session key for authenticator in FAST armor field</param> /// <param name="fastOptions">FAST options</param> /// <param name="apOptions">AP options in FAST armor field</param> /// <param name="data">Authorization data</param> public void SendTgsRequestWithExplicitFast( string sName, KdcOptions kdcOptions, Asn1SequenceOf<PA_DATA> innerSeqPaData, Asn1SequenceOf<PA_DATA> outerSeqPaData, EncryptionKey subKey, FastOptions fastOptions, ApOptions apOptions, AuthorizationData data = null) { Context.Subkey = subKey; Context.ReplyKey = subKey; string domain = this.Context.Realm.Value; PrincipalName sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName.Split('/'))); KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname, data); Asn1BerEncodingBuffer bodyBuffer = new Asn1BerEncodingBuffer(); kdcReqBody.BerEncode(bodyBuffer); //Create PA-TGS-REQ APOptions option = new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.None)); ChecksumType checksumType = KerberosUtility.GetChecksumType(Context.SelectedEType); KerberosApRequest apRequest = CreateApRequest( option, Context.Ticket, subKey, data, KeyUsageNumber.TG_REQ_PA_TGS_REQ_padataOR_AP_REQ_Authenticator, checksumType, bodyBuffer.Data); PaTgsReq paTgsReq = new PaTgsReq(apRequest.Request); Asn1SequenceOf<PA_DATA> tempPaData = null; if (outerSeqPaData == null || outerSeqPaData.Elements == null || outerSeqPaData.Elements.Length == 0) { tempPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paTgsReq.Data }); } else { tempPaData.Elements = new PA_DATA[outerSeqPaData.Elements.Length + 1]; Array.Copy(outerSeqPaData.Elements, tempPaData.Elements, outerSeqPaData.Elements.Length); tempPaData.Elements[outerSeqPaData.Elements.Length] = paTgsReq.Data; } //Create explicit FAST armor EncryptionKey explicitSubkey = KerberosUtility.MakeKey( Context.SelectedEType, "Password04!", "This is a salt"); Authenticator plaintextAuthenticator = CreateAuthenticator(Context.ArmorTicket, null, explicitSubkey); KerberosApRequest apReq = new KerberosApRequest(Context.Pvno, new APOptions(KerberosUtility.ConvertInt2Flags((int)apOptions)), Context.ArmorTicket, plaintextAuthenticator, KeyUsageNumber.AP_REQ_Authenticator); FastArmorApRequest explicitArmor = new FastArmorApRequest(apReq.Request); //Create armor key var armorKey = GetArmorKey(Context.ArmorSessionKey, subKey, explicitSubkey); Context.FastArmorkey = armorKey; //Create PA-FX-FAST var pafxfast = CreateTgsPaFxFast(armorKey, Context.ArmorTicket, fastOptions, apOptions, tempPaData, sName, paTgsReq.Data.padata_value.ByteArrayValue, explicitArmor); PA_DATA[] elements; if (outerSeqPaData != null && outerSeqPaData.Elements.Length > 0) { elements = new PA_DATA[outerSeqPaData.Elements.Length + 1]; Array.Copy(outerSeqPaData.Elements, elements, outerSeqPaData.Elements.Length); elements[outerSeqPaData.Elements.Length] = pafxfast.Data; elements[outerSeqPaData.Elements.Length + 1] = paTgsReq.Data; } else { elements = new PA_DATA[] { pafxfast.Data, paTgsReq.Data }; } Asn1SequenceOf<PA_DATA> seqPaData = new Asn1SequenceOf<PA_DATA>(); KerberosTgsRequest tgsRequest = new KerberosTgsRequest(KerberosConstValue.KERBEROSV5, kdcReqBody, new Asn1SequenceOf<PA_DATA>(elements), Context.TransportType); this.SendPdu(tgsRequest); this.testSite.Log.Add(LogEntryKind.Debug, "Send FAST TGS request."); }
/// <summary> /// Create and send FAST TGS request /// </summary> /// <param name="sName">Service principal name</param> /// <param name="kdcOptions">KDC options</param> /// <param name="innerSeqPaData">A sequence of preauthentication data in FAST request</param> /// <param name="outerSeqPaData">A sequence of preauthentication data</param> /// <param name="subKey">Sub-session key for authenticator in FAST armor field</param> /// <param name="fastOptions">FAST options</param> /// <param name="apOptions">AP options in FAST armor field</param> /// <param name="data">Authorization data</param> public void SendTgsRequestWithFastHideCName( string sName, PrincipalName cName, KdcOptions kdcOptions, Asn1SequenceOf<PA_DATA> innerSeqPaData, Asn1SequenceOf<PA_DATA> outerSeqPaData, EncryptionKey subKey, ApOptions apOptions, AuthorizationData data = null) { var fastOptions = new Protocols.TestTools.StackSdk.Security.KerberosV5.Preauth.FastOptions( KerberosUtility.ConvertInt2Flags((int)FastOptionFlags.Hide_Client_Names)); Context.Subkey = subKey; Context.ReplyKey = subKey; string domain = this.Context.Realm.Value; PrincipalName sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName.Split('/'))); KDC_REQ_BODY kdcReqBody = CreateKdcRequestBody(kdcOptions, sname, data); kdcReqBody.cname = cName; Asn1BerEncodingBuffer bodyBuffer = new Asn1BerEncodingBuffer(); kdcReqBody.BerEncode(bodyBuffer); APOptions option = new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.None)); ChecksumType checksumType = KerberosUtility.GetChecksumType(Context.SelectedEType); KerberosApRequest apRequest = CreateApRequest( option, Context.Ticket, subKey, data, KeyUsageNumber.TG_REQ_PA_TGS_REQ_padataOR_AP_REQ_Authenticator, checksumType, bodyBuffer.Data); PaTgsReq paTgsReq = new PaTgsReq(apRequest.Request); Asn1SequenceOf<PA_DATA> tempPaData = null; if (outerSeqPaData == null || outerSeqPaData.Elements == null || outerSeqPaData.Elements.Length == 0) { tempPaData = new Asn1SequenceOf<PA_DATA>(new PA_DATA[] { paTgsReq.Data }); } else { tempPaData.Elements = new PA_DATA[outerSeqPaData.Elements.Length + 1]; Array.Copy(outerSeqPaData.Elements, tempPaData.Elements, outerSeqPaData.Elements.Length); tempPaData.Elements[outerSeqPaData.Elements.Length] = paTgsReq.Data; } var armorKey = GetArmorKey(Context.SessionKey, subKey); var pafxfast = CreateTgsPaFxFast(armorKey, Context.Ticket, fastOptions, apOptions, tempPaData, sName, paTgsReq.Data.padata_value.ByteArrayValue); Context.FastArmorkey = armorKey; PA_DATA[] elements; if (outerSeqPaData != null && outerSeqPaData.Elements.Length > 0) { elements = new PA_DATA[outerSeqPaData.Elements.Length + 1]; Array.Copy(outerSeqPaData.Elements, elements, outerSeqPaData.Elements.Length); elements[outerSeqPaData.Elements.Length] = pafxfast.Data; elements[outerSeqPaData.Elements.Length + 1] = paTgsReq.Data; } else { elements = new PA_DATA[] { pafxfast.Data, paTgsReq.Data }; } Asn1SequenceOf<PA_DATA> seqPaData = new Asn1SequenceOf<PA_DATA>(); KerberosTgsRequest tgsRequest = new KerberosTgsRequest(KerberosConstValue.KERBEROSV5, kdcReqBody, new Asn1SequenceOf<PA_DATA>(elements), Context.TransportType); this.SendPdu(tgsRequest); this.testSite.Log.Add(LogEntryKind.Debug, "Send FAST TGS request."); }
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)); }
/// <summary> /// Encode this class into byte array. /// </summary> /// <returns>The byte array of the class.</returns> public override byte[] ToBytes() { Asn1BerEncodingBuffer asBerBuffer = new Asn1BerEncodingBuffer(); this.Request.BerEncode(asBerBuffer, true); return asBerBuffer.Data; }
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(); }
/// <summary> /// Encode the Krb Error to bytes /// </summary> /// <param name="buffer">The byte array to be decoded.</param> public override byte[] ToBytes() { Asn1BerEncodingBuffer errorBerBuffer = new Asn1BerEncodingBuffer(); this.KrbError.BerEncode(errorBerBuffer, true); if (transportType == TransportType.TCP) { return KerberosUtility.WrapLength(errorBerBuffer.Data, true); } else { return errorBerBuffer.Data; } }
public PaEncTimeStamp(string timeStamp, int usec, EncryptionType eType, string password, string salt) { this.TimeStamp = timeStamp; this.Usec = usec; byte[] key = KeyGenerator.MakeKey(eType, password, salt); this.Key = new EncryptionKey(new KerbInt32((long)eType), new Asn1OctetString(key)); // create a timestamp PA_ENC_TS_ENC paEncTsEnc = new PA_ENC_TS_ENC(new KerberosTime(this.TimeStamp), new Microseconds(this.Usec)); Asn1BerEncodingBuffer currTimeStampBuffer = new Asn1BerEncodingBuffer(); paEncTsEnc.BerEncode(currTimeStampBuffer); var rawData = currTimeStampBuffer.Data; KerberosUtility.OnDumpMessage("KRB5:PA-ENC-TS-ENC", "Encrypted Timestamp Pre-authentication", KerberosUtility.DumpLevel.PartialMessage, rawData); // encrypt the timestamp byte[] encTimeStamp = KerberosUtility.Encrypt((EncryptionType)this.Key.keytype.Value, this.Key.keyvalue.ByteArrayValue, rawData, (int)KeyUsageNumber.PA_ENC_TIMESTAMP); // create an encrypted timestamp PA_ENC_TIMESTAMP paEncTimeStamp = new PA_ENC_TIMESTAMP(new KerbInt32(this.Key.keytype.Value), null, new Asn1OctetString(encTimeStamp)); Asn1BerEncodingBuffer paEncTimestampBuffer = new Asn1BerEncodingBuffer(); paEncTimeStamp.BerEncode(paEncTimestampBuffer, true); Data = new PA_DATA(new KerbInt32((long)PaDataType.PA_ENC_TIMESTAMP), new Asn1OctetString(paEncTimestampBuffer.Data)); }