前陣子完成一個案子,這案子要驗證 RFID 卡的文件內容是否可信。
本文內容是工作過程中寫出來的一個練習程式與小工具。
此工具用途為查看本地的 X509 證書資訊,並回報其是否有效。
工具名稱為 x509-cert-info。
程式內容使用了 OpenSSL 函數庫。OpenSSL 函數庫內容很多,但公式文件的內容很少,就是些草稿。
我將陸續整理工作過程中得到的相關經驗,記錄在部落格上。
x509-cert-info
show-x509-info.h 只是一些自己定義的代號。與 OpenSSL 無關,不多解釋。
show-x509-info.c 定義了函數 show_x509_info()。
此函數要求指定證書(certificate)的文件路徑(cert_filepath)與文件格式(inform)。
讀入的X509資訊放入指標 out_x509 傳回,另將詳細的函數執行狀態存入 state。
函數回傳值若為 TRUE,則此證書的格式正確且日期尚在有效期間內。
在 OpenSSL 函數庫中,主要的資料輸出入行為是透過它定義的 BIO 類別進行。
但也提供其他的方式,例如透過 C 標準庫的 FILE。
本文還不會用到 BIO ,只用 FILE 讀入指定的文件內容。
處理 DER 格式的X509證書需要使用 d2i_X509, i2d_X509 家族函數,細節宣告於 x509.h (預設位於/usr/include/openssl目錄)。
處理 PEM 格式的X509證書則需要使用 PEM_read_X509, PEM_write_X509 家族函數,細節宣告於 pem.h。
請自行閱讀其標頭檔了解更多內容。
讀入的 X509 結構細節,查看 x509.h 的 struct x509_st。有些內容可以直接取出,例如有效日期。
有些內容則要配合指定的方法,例如 issuer_name 與 subject_name。
至於有哪些方法可以用,請查看 x509.h ,善用你的聯想力。
x509-cert-info 是主程式,它會根據使用者指定的證書路徑與格式,調用函數 show_X509_info() 顯示內容。
並根據 state 回報執行狀態。外部工具 – 例如 shell – 就可以根據程式狀態碼得知證書是否有效。
編譯參數如下:
gcc -lssl -o x509-cert-info x509-cert-info.c show-x509-info.c
測試
建立測試用的證書
使用 openssl 工具的 req 選項可以建立一份證書。
在此例中,我們只是要一份測試程式功能的證書,不必考慮公信力,所以建立一份我們自己背書的證書即可。
用例如下:
# create PEM format certificate
openssl req \
-x509 -days 30 -newkey rsa:1024 \
-subj "/CN=rocksaying/O=Rock's blog./C=TW" \
-out mycert.pem
# create DER format certificate
openssl req \
-x509 -days 30 -newkey rsa:1024 \
-subj "/CN=rocksaying/O=Rock's blog./C=TW" \
-out mycert.der -outform DER
days 是有效天數。subj 是證書名稱,在此同時也會是發照者名稱,文字格式是 X.500。
證書格式通常使用 DER 或 PEM。
DER 是內容為二進位碼的證書,而 PEM 則是 Base64 編碼加上特定檔頭的證書。
這兩者可以互轉。例如我有一份 DER 格式的X509證書,要轉成 PEM 格式的話,只需要以 openssl 工具操作:
openssl x509 -in x509.crt -inform DER -out x509.pem -outform PEM
,即可轉得。
由於兩種格式可以互轉,所以建立證書時,通常只需要選擇其中一種格式發布。
測試結果
建立一份 PEM 格式的X509證書,檔名為 mycert.pem。測試的輸出過程如下:
$ openssl req \
> -x509 -days 30 -newkey rsa:1024 \
> -subj "/CN=rocksaying/O=Rock's blog./C=TW" \
> -out mycert.pem
Generating a 1024 bit RSA private key
................++++++
...........++++++
writing new private key to 'privkey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
$ ./x509-cert-info mycert.pem
Information of mycert.pem:
ERROR: X509_IS_INVALID
$ ./x509-cert-info mycert.pem PEM
Information of mycert.pem:
Issuer name: /CN=rocksaying/O=Rock's blog./C=TW
Subject name: /CN=rocksaying/O=Rock's blog./C=TW
Validity from: 110727071525Z
Validity till: 110826071525Z
我先不帶參數地交給 x509-cert-info 查看內容,由於 x509-cert-info 預設格式為 DER ,故判定證書格式不符。
接著指定選項 PEM,就可成功查看證書內容。
openssl 工具的 x509 選項也可以查看證書內容。用例如: openssl x509 -text -in mycert.pem
。
可與本文程式所輸出的結果對照,確認程式無誤。
References
-
PEM_read_X509()
-
d2i_X509_fp()
-
HOWTO certificates
-
OpenSSL Command-Line HOWTO - Paul Heinlein.
OpenSSL 文件至今仍在草稿階段,有許多函數與結構的內容並未提及。
程序員需要自己查看 OpenSSL 的標頭文件(預設位於/usr/include/openssl)找尋有用的內容。
此外,OpenSSL 的源碼可說是必要的參考文件。
我建議將閱讀重點放在 apps 目錄內的源碼,其內容對應 openssl 命令項目,較容易理解其工作內容。
相關文章
樂多舊網址: http://blog.roodo.com/rocksaying/archives/16158079.html
樂多舊回應