/// <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("errorToken"); } byte[] errorBody = KileUtility.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)KileUtility.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)); KileKrbError error = new KileKrbError(); error.FromBytes(errorBody); return(error); }
/// <summary> /// Decode GSSAPI token to AP-REP /// </summary> /// <param name="token">GSSAPI token</param> /// <returns></returns> private KerberosApResponse GetApResponseFromToken(byte[] token, KerberosConstValue.GSSToken gssToken = KerberosConstValue.GSSToken.GSSSPNG) { if (gssToken == KerberosConstValue.GSSToken.GSSSPNG) { token = KerberosUtility.DecodeNegotiationToken(token); } if (token[0] == KerberosConstValue.KERBEROS_TAG) { byte[] apData = KerberosUtility.VerifyGssApiTokenHeader(token, this.client.OidPkt); // Check if it has a two-byte tok_id if (null == apData || apData.Length <= sizeof(TOK_ID)) { throw new FormatException( "Data length is shorter than a valid AP Response data length."); } // verify TOK_ID byte[] tokenID = ArrayUtility.SubArray <byte>(apData, 0, sizeof(TOK_ID)); Array.Reverse(tokenID); TOK_ID id = (TOK_ID)BitConverter.ToUInt16(tokenID, 0); if (!id.Equals(TOK_ID.KRB_AP_REP)) { throw new Exception("ApResponse Token ID should be KRB_AP_REP"); } // Get apBody token = ArrayUtility.SubArray(apData, sizeof(TOK_ID)); } KerberosApResponse apRep = new KerberosApResponse(); apRep.FromBytes(token); // Get the current encryption type, cipher data EncryptionType encryptType = (EncryptionType)apRep.Response.enc_part.etype.Value; byte[] cipherData = apRep.Response.enc_part.cipher.ByteArrayValue; byte[] sessionKey = this.Context.ApSessionKey.keyvalue.ByteArrayValue; // decrypt enc_part to clear text byte[] clearText = KerberosUtility.Decrypt(encryptType, sessionKey, cipherData, (int)KeyUsageNumber.AP_REP_EncAPRepPart); // decode enc_part Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(clearText); apRep.ApEncPart = new EncAPRepPart(); apRep.ApEncPart.BerDecode(decodeBuffer); this.client.UpdateContext(apRep); return(apRep); }