/// <summary> /// Add a token header for AP request/response, wrap token or getmic token to make them a complete token. /// </summary> /// <param name="tokenBody">The AP request/response, wrap token or getmic token. /// This argument can be null.</param> /// <returns>The completed token.</returns> public static byte[] AddGssApiTokenHeader(byte[] tokenBody, KerberosConstValue.OidPkt oidPkt = KerberosConstValue.OidPkt.KerberosToken, KerberosConstValue.GSSToken gssToken = KerberosConstValue.GSSToken.GSSSPNG) { List <byte> gssDataList = new List <byte>(); gssDataList.Add(KerberosConstValue.KERBEROS_TAG); // kerberos oid (1.2.840.113554.1.2.2) byte[] oid; oid = KerberosConstValue.GetKerberosOid(); if (tokenBody == null) { tokenBody = new byte[0]; } int length = tokenBody.Length + oid.Length; if (length > 127) { // If the indicated value is 128 or more, it shall be represented in two or more octets, // with bit 8 of the first octet set to "1" and the remaining bits of the first octet // specifying the number of additional octets. The subsequent octets carry the value, // 8 bits per octet, most significant digit first. [rfc 2743] int temp = length; int index = 1; List <byte> lengthList = new List <byte>(); lengthList.Add((byte)(temp & 0xFF)); while ((temp >>= 8) != 0) { index++; lengthList.Add((byte)(temp & 0xFF)); } gssDataList.Add((byte)(0x80 | index)); lengthList.Reverse(); gssDataList.AddRange(lengthList.ToArray()); } else { // If the indicated value is less than 128, it shall be represented in a single octet with bit 8 // (high order) set to "0" and the remaining bits representing the value. [rfc 2743] gssDataList.Add((byte)length); } gssDataList.AddRange(oid); gssDataList.AddRange(tokenBody); if (gssToken == KerberosConstValue.GSSToken.GSSAPI) { return(gssDataList.ToArray()); } else { return(KerberosUtility.EncodeInitialNegToken(gssDataList.ToArray(), oidPkt)); } }