/// <summary> /// Wrap a length before the buffer. /// </summary> /// <param name="buffer">The buffer to be wrapped.</param> /// <param name="isBigEndian">Specify if the length is Big-Endian.</param> /// <returns>The buffer added length.</returns> public static byte[] WrapLength(byte[] buffer, bool isBigEndian) { if (isBigEndian) { return(ArrayUtility.ConcatenateArrays( BitConverter.GetBytes(KerberosUtility.ConvertEndian((uint)buffer.Length)), buffer)); } else { return(ArrayUtility.ConcatenateArrays(BitConverter.GetBytes(buffer.Length), buffer)); } }
/// <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> /// Client initialize with server token /// </summary> /// <param name="serverToken">Server token</param> private void ClientInitialize(byte[] serverToken) { KerberosApResponse apRep = this.GetApResponseFromToken(serverToken, KerberosConstValue.GSSToken.GSSAPI); this.VerifyApResponse(apRep); token = null; if ((contextAttribute & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle) { KerberosApResponse apResponse = this.CreateApResponse(null); var apBerBuffer = new Asn1BerEncodingBuffer(); if (apResponse.ApEncPart != null) { // Encode enc_part apResponse.ApEncPart.BerEncode(apBerBuffer, true); EncryptionKey key = this.Context.ApSessionKey; if (key == null || key.keytype == null || key.keyvalue == null || key.keyvalue.Value == null) { throw new ArgumentException("Ap session key is not valid"); } // Encrypt enc_part EncryptionType eType = (EncryptionType)key.keytype.Value; byte[] cipherData = KerberosUtility.Encrypt( eType, key.keyvalue.ByteArrayValue, apBerBuffer.Data, (int)KeyUsageNumber.AP_REP_EncAPRepPart); apResponse.Response.enc_part = new EncryptedData(new KerbInt32((int)eType), null, new Asn1OctetString(cipherData)); } // Encode AP Response apResponse.Response.BerEncode(apBerBuffer, true); if ((this.Context.ChecksumFlag & ChecksumFlags.GSS_C_DCE_STYLE) == ChecksumFlags.GSS_C_DCE_STYLE) { // In DCE mode, the AP-REP message MUST NOT have GSS-API wrapping. // It is sent as is without encapsulating it in a header ([RFC2743] section 3.1). this.token = apBerBuffer.Data; } else { this.token = KerberosUtility.AddGssApiTokenHeader(ArrayUtility.ConcatenateArrays( BitConverter.GetBytes(KerberosUtility.ConvertEndian((ushort)TOK_ID.KRB_AP_REP)), apBerBuffer.Data)); } } this.needContinueProcessing = false; // SEC_E_OK; }
public static byte[] AddGssApiTokenHeader(KerberosApRequest request, KerberosConstValue.OidPkt oidPkt = KerberosConstValue.OidPkt.KerberosToken, KerberosConstValue.GSSToken gssToken = KerberosConstValue.GSSToken.GSSSPNG) { byte[] encoded = request.ToBytes(); byte[] token = KerberosUtility.AddGssApiTokenHeader(ArrayUtility.ConcatenateArrays( BitConverter.GetBytes(KerberosUtility.ConvertEndian((ushort)TOK_ID.KRB_AP_REQ)), encoded), oidPkt, gssToken); return(token); }