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 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> /// 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; } }
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); }