/// <summary> /// Create a Gss_Wrap [RFC4121] token. /// </summary> /// <param name="isEncrypted">If encrypt the message.</param> /// <param name="message">The message to be wrapped. This argument can be null.</param> /// <param name="isInitiator">If the sender is initiator.</param> /// <returns>The created Gss_Wrap token.</returns> private Token4121 GssWrap4121(bool isEncrypted, byte[] message, bool isInitiator) { var token = new Token4121(Context); var tokenHeader = new TokenHeader4121(); tokenHeader.tok_id = TOK_ID.Wrap4121; tokenHeader.flags = isEncrypted ? WrapFlag.Sealed : WrapFlag.None; if (!isInitiator) { tokenHeader.flags |= WrapFlag.SentByAcceptor; } if (Context.AcceptorSubKey != null) { tokenHeader.flags |= WrapFlag.AcceptorSubkey; } tokenHeader.filler = KerberosConstValue.TOKEN_FILLER_1_BYTE; tokenHeader.ec = 16; // [MS-KILE] The RRC field ([RFC4121] section 4.2.5) is 12 if no encryption is requested or 28 if encryption is requested. tokenHeader.rrc = isEncrypted ? (ushort)28 : (ushort)12; tokenHeader.snd_seq = Context.CurrentLocalSequenceNumber; token.TokenHeader = tokenHeader; token.Data = message; return(token); }
/// <summary> /// Create a Gss_GetMic [RFC4121] token. /// </summary> /// <param name="message">The message to be wrapped. This argument can be null.</param> /// <param name="isInitiator">If the sender is initiator.</param> /// <returns>The created Gss_GetMic token.</returns> private Token4121 GssGetMic4121(byte[] message, bool isInitiator) { var token = new Token4121(Context); var tokenHeader = new TokenHeader4121(); tokenHeader.tok_id = TOK_ID.Mic4121; tokenHeader.flags = WrapFlag.None; if (!isInitiator) { tokenHeader.flags |= WrapFlag.SentByAcceptor; } if (Context.AcceptorSubKey != null) { tokenHeader.flags |= WrapFlag.AcceptorSubkey; } tokenHeader.filler = KerberosConstValue.TOKEN_FILLER_1_BYTE; tokenHeader.ec = KerberosConstValue.TOKEN_FILLER_2_BYTE; tokenHeader.rrc = KerberosConstValue.TOKEN_FILLER_2_BYTE; tokenHeader.snd_seq = Context.CurrentLocalSequenceNumber; token.TokenHeader = tokenHeader; token.Data = message; return(token); }
/// <summary> /// Decode a Gss_Wrap token from security buffers /// </summary> /// <param name="context">The context of decoding</param> /// <param name="securityBuffers">Security buffers</param> /// <returns>The decoded Gss_Wrap token.</returns> internal static KerberosPdu GssUnWrapEx(KerberosContext context, SecurityBuffer[] securityBuffers) { KerberosPdu pdu = null; EncryptionKey key = context.ContextKey; switch ((EncryptionType)key.keytype.Value) { case EncryptionType.AES128_CTS_HMAC_SHA1_96: case EncryptionType.AES256_CTS_HMAC_SHA1_96: var token4121Pdu = new Token4121(context); token4121Pdu.FromSecurityBuffers(securityBuffers); pdu = token4121Pdu; break; case EncryptionType.DES_CBC_CRC: case EncryptionType.DES_CBC_MD5: case EncryptionType.RC4_HMAC: case EncryptionType.RC4_HMAC_EXP: var token1964or4757Pdu = new Token1964_4757(context); token1964or4757Pdu.FromSecurityBuffers(securityBuffers); pdu = token1964or4757Pdu; break; default: throw new NotSupportedException("The Encryption Type can only be AES128_CTS_HMAC_SHA1_96, " + "AES256_CTS_HMAC_SHA1_96, DES_CBC_CRC, DES_CBC_MD5, RC4_HMAC or RC4_HMAC_EXP."); } return(pdu); }
internal static bool GssVerifyMicEx(KerberosContext context, SecurityBuffer[] securityBuffers, out KerberosPdu pdu) { pdu = null; bool isVerified = true; EncryptionKey key = context.ContextKey; switch ((EncryptionType)key.keytype.Value) { case EncryptionType.AES128_CTS_HMAC_SHA1_96: case EncryptionType.AES256_CTS_HMAC_SHA1_96: var micPdu4121 = new Token4121(context); try { micPdu4121.FromSecurityBuffers(securityBuffers); } catch (FormatException) { isVerified = false; } pdu = micPdu4121; break; case EncryptionType.DES_CBC_CRC: case EncryptionType.DES_CBC_MD5: case EncryptionType.RC4_HMAC: case EncryptionType.RC4_HMAC_EXP: var micPdu1964_4757 = new Token1964_4757(context); try { micPdu1964_4757.FromSecurityBuffers(securityBuffers); } catch (FormatException) { isVerified = false; } pdu = micPdu1964_4757; break; default: throw new NotSupportedException("The Encryption Type can only be AES128_CTS_HMAC_SHA1_96, " + "AES256_CTS_HMAC_SHA1_96, DES_CBC_CRC, DES_CBC_MD5, RC4_HMAC or RC4_HMAC_EXP."); } return(isVerified); }
/// <summary> /// Decrypt a request or response /// </summary> /// <param name="token">A token containing encrypted data.</param> /// <param name="sentFromClient">True if the token is a request, false is a response</param> /// <returns>Plain-text data.</returns> private byte[] Decrypt(byte[] token, bool sentFromClient) { KileContext context = sentFromClient ? (KileContext)kileDecoder.serverContext : (KileContext)kileDecoder.clientContext; KilePdu pdu = KileRole.GssUnWrap(context, token); Token4121 token4121Pdu = pdu as Token4121; if (token4121Pdu != null) { return(token4121Pdu.Data); } Token1964_4757 token1964or4757Pdu = pdu as Token1964_4757; if (token1964or4757Pdu != null) { return(token1964or4757Pdu.Data); } throw new InvalidOperationException("Token type is not supported."); }