回覆列表
  • 1 # 使用者8400807278479

    OpenSSL是有自己的配置的檔案的,作為一個庫,也是會從專門的地方讀取它的配置檔案。這個配置檔案位於編譯時--prefix指定的目錄的ssl/openssl.cnf(如果自己編譯的情況下,否則在發行版的約定位置)。總體的組織方式是INI方式,但是又比INI格式複雜很多。

    一個OpenSSL的配置檔案中包含很多的段落,叫做Section。每一個Section都會有[section_name]開頭標識,整個檔案的第一個Section是沒有[section_name]的,這個第一個Section就叫做預設Section。當查詢一個配置的時候,會首先去有名字的Section去尋找,如果找到了就使用有名字的Section的配置,但是如果沒有找到,就會去預設的Section去找,也就是在配置檔案的開頭找。一個簡單的配置檔案示例如下:

    HOME = .

    RANDFILE = $ENV::HOME/.rnd

    oid_section = new_oids

    openssl_conf = openssl_def

    [openssl_def]

    engines = engine_section

    [engine_section]

    qat = qat_section

    [qat_section]

    engine_id = qat

    dynamic_path = /home/lbc/handshaker_qat/lib/engines-1.1/qat.so

    default_algorithms = ALL

    [ new_oids ]

    tsa_policy1 = 1.2.3.4.1

    tsa_policy2 = 1.2.3.4.5.6

    tsa_policy3 = 1.2.3.4.5.7

    可以看到預設Section除了充當一個補充查詢的功能,還能充當一個配置架構的定義功能。因為例如oid_section這個變數在後續的Section不會被定義,如果在開頭定義了,那麼就相當於OpenSSL的庫邏輯可以透過這個配置項找到接下來要真正使用的Section,相當於一個在配置檔案中配合OpenSSL程式的邏輯實現一個條件程式設計的判斷邏輯。

    配置檔案中用#表示註釋行,整個的配置都是K-V結構的。name=value。name和value的前導或者尾隨空格會被忽略。值包含空格的話需要使用引號。

    OpenSSL的配置檔案本身包含了程式語言的變數概念。在各個Section中都可以定義變數。每個Section中定義的變數的作用於都是在本Section內部,在本Section內部使用變數的方法是$var或者${var}。但是跨Section的變數引用仍然是可行的,只是需要用到其他Section的Section Name。引用的方式是"$section_name::name"或"${section_name::name}"。

    HOME=/tmp

    RANDFILE= ${ENV::HOME}/.rnd

    configdir=$ENV::HOME/config

    [ section_one ]

    value1 = section_three

    value2 = @section_three

    [section_three]

    greeting = $section_one::message

    可以看到ENV變數就是全域性Section,HOME本身就是一個變數的定義,引用這個HOME變數的方法是${ENV::HOME}或者$ENV::HOME。section_one中定義了兩個變數,value1是直接賦值了section_three的名字,也就是說,一個Section本身也是一個變數,變數的名字就是Section的名字。value2使用了@符號,在OpenSSL的配置檔案中,@符號用於引用一個Section,所以這裡是否使用@是等價的。

    OpenSSL的配置子系統被放到了Crypto庫中,程式碼位於crypto/conf目錄。這一整個配置引擎實現的就是上述的變數和判斷邏輯的引擎支援。整個配置引擎也被做成了框架,雖然只有Windows和Linux兩種變數,框架的典型表示就是方法表,配置引擎是CONF_METHOD結構體作為方法表。這個方法表定義的是比較高層次的,配置檔案的開啟載入釋放等操作。真正被其他模組使用的函式位於openssl/conf.h中。裡面有兩部分,已不是NCONF_開頭的目前被其他模組真正使用的配置引擎的函式介面,另外一部分是CONF_開頭的與動態載入模組相關的函式,一般用於ENGINE的模組根據配置來動態的載入。之所以開頭是NCONF_是因為之前存在一套老的配置模組的使用介面以CONF_,重構過之後為了保持相容就起了NCONF_的名字,而老式的CONF_開頭的配置引擎的介面函式仍然可以繼續使用,但是準備廢棄。

    我們注意到在所有的OpenSSL配置檔案中都會有一個位於預設Section的固定的openssl_conf變數,這個變數的名字是固化寫死在openssl程式中的,OpenSSL的邏輯就是使用這個變數找到後面的對應的邏輯,所以在OpenSSL的配置檔案中給這個變數賦值一個Secssion的名字就是必須要做的實行。

    還有一個讓大部分人都會費解的new_oids的Section。這個oid相當於是OpenSSL的一個數據庫引擎。OpenSSL用一個大型的陣列整數來存放各種存在性定義。這個大陣列就是位於obj_dat.h中的五個常數陣列定義。雖然這些陣列定義的一些資訊是一個龐大的倉庫,但是對外都會使用obj_dat.c中提供的一系列函式轉換到OpenSSL程式可以識別的資料結構。這個資料結構通常是ASN格式的(ASN1_OBJECT)。而這裡的配置就是用來定義新的ASN1結構體的。雖然OpenSSL中相容幷包的定義了大部分的情況,但是仍然提供一種方式出來給配置定義是很合理的思路。大部分情況下這個配置都會是tsa_policy相關的內容,本質上是時間戳。使用openssl ts子命令可以訪問到這個時間戳模組(RFC 3161)。這個時間戳模組是用於服務端和客戶端的時間伺服器認證的。openssl ts命令可以方便的復原客戶端和服務端的時間戳認證服務的場景,詳情可以檢視幫助檔案。

    OpenSSL的主程式雖然是硬編碼了openssl_conf變數用來查詢到配置,不同的其他模組還硬編碼了其他的變數名字來查詢到配置項。例如EVP模組中定義了alg_section,這個Section名字在OpenSSL的配置檔案中出現的時候就代表了對EVP模組的配置。所以可以看出來,OpenSSL中不同的功能模組在使用配置檔案的方式。不同的模組可以直接的硬編碼一個Section的名字,然後只要這個名字在配置中出現,就會被這個模組解析到。這個特殊的Section是不需要關聯到OpenSSL主程式的openssl_conf變數的。其他的類似的這種硬編碼的變數還有ssl_conf用來配置SSL相關的內容,還有engines變數用來關聯ENGINE引擎相關的配置。

  • 中秋節和大豐收的關聯?
  • 果寶特攻2的主題曲的歌詞是什麼?