修改 OpenVPN 實現加密演算法的自動協商
由另一篇博中的分析可知,OpenVPN 中有兩個加解密通道。一條是標準的 SSL 協議通道,被 OpenVPN 用於協商自己所用的金鑰。這個通道的加密演算法當然也是通過 SSL 協議來進行協商的,可以通過
--tls-cipher
選項來進行配置。另一條是 OpenVPN 自己的加解密通道,用於交換實際的資料,也就是虛擬網絡卡抓到的 IP 報文。這個通道的加密演算法則是通過
--cipher
和 --auth
兩個選項,分別在通調兩端指定的。
對於第二條通道的加密演算法,必須要同時在兩端分別指定一致的選項,有時候不是很方便(當然,我研究的還是 2.1.1 版本的 OpenVPN ,不知道最新的版本還是不是這樣)。比如說,我想通過在服務端修改配置,指定加密演算法,然後讓連線我的客戶端自動用同一個演算法。最簡單的修改思路,就是借用第一條通道中的演算法協商機制,從 SSL 物件中取得協商出來的演算法。
具體做法就是:
首先,在函式 do_init_crypto_tls_c1()
中,去掉對函式 init_key_type()
的呼叫。這個呼叫就是根據
--cipher
和 --auth
選項進行演算法配置的地方,我們要動態協商,自然是不需要這個了。
但同時,這會引起接下來一個步驟的錯誤。在函式 crypto_adjust_frame_parameters()
中,會根據之前配置的演算法進行報文中金鑰空間的分配。現在還不知道演算法,怎麼知道要分配多少空間呢?就只能改成最大值了。分別改為
MAX_CIPHER_KEY_LENGTH
和 MAX_HMAC_KEY_LENGTH
就行了。當然,這樣改不僅浪費空間,而且也不夠嚴謹,因為 key length 和 IV length 不是一回事,卻只能都用
MAX_CIPHER_KEY_LENGTH
最後就是在 SSL 協商好之後,從裡面取加密演算法了。具體位置在 key_method_2_write()
和 key_method_2_read()
兩個函式中,對
generate_key_expansion()
函式的呼叫之處了。在呼叫之前,初始化一下 key_type
就行了:
1 2 3 4 5 6 7 8 9 |
|
這樣就行了。