周末在家無趣丝蹭,研究了一個golang里面的Certificate.Verify函數(shù)介粘。
golang的官方定義在這里:https://golang.org/pkg/crypto/x509/#Certificate.Verify
函數(shù)原型聲明如下:
func (c Certificate) Verify(opts VerifyOptions) (chains [][]Certificate, err error)
其中:
- c *Certificate是待驗證的證書
- 參數(shù)opts定義如下玄帕,我們只關(guān)注這兩個成員。
type VerifyOptions struct {
...
Roots *CertPool // if nil, the system roots are used
Intermediates *CertPool
...
}
- 返回值是一個二維數(shù)組證書译秦。
這個函數(shù)的功能是:
Verify attempts to verify c by building one or more chains from c to a certificate in opts.Roots, using certificates in opts.Intermediates if needed. If successful, it returns one or more chains where the first element of the chain is c and the last element is from opts.Roots.
If opts.Roots is nil and system roots are unavailable the returned error will be of type SystemRootsError.
解釋一下就是:
- 試圖找出所有從c開始到opts.Roots中的證書為止的所有的證書鏈。
- 這其中會有多條證書鏈,所以返回類型是二維數(shù)組[][]*Certificate筑悴,每一條鏈都是一個一維數(shù)組表示们拙。
- 對每一條鏈:
- 第一個元素都是c
- 最后一個元素是opts.Roots中的成員。
- 中間元素都是opts.Intermediates中的成員阁吝。中間元素可能沒有砚婆,則此條證書鏈只包含兩個成員c和opts.Roots成員。
- 如果opts.Roots為空求摇,那么opts.Roots使用系統(tǒng)根證書射沟。
舉一個例子:
假設(shè)存在證書鏈簽出關(guān)系:C1 -> C2 -> C3 -> C4,即C1簽出C2与境,C2簽出C3验夯,C3簽出C4;現(xiàn)在使用函數(shù):
C4.Verify(VerifyOptions {
Roots : [...],
Intermediates: [...],
})
我們根據(jù)Intermediates和Roots的值不同摔刁,比較輸出結(jié)果:
Roots | Intermediates | 輸出 | 說明 |
---|---|---|---|
[C1, C2, C3] | [] | [C4, C3] | <none> |
[] | [C1, C2, C3] | error | 找不到Roots挥转,又不屬于系統(tǒng)根證書 |
[C3] | [C1, C2, C3] | [C4, C3] | 這個C3就是Roots中的C3 |
[C1, C2, C3] | [C3] | [C4, C3] [C4, C3, C2] |
第一個C3是Roots.C3 第二個C3是Intermediates.C3 |
[C1, C2, C3] | [C1, C2, C3] | [C4, C3] [C4, C3, C2] [C4, C3, C2, C1] |
C4 -> C3.R C4 -> C3.I -> C2.R C4 -> C3.I -> C2.I -> C1.R |
... | ... | ... | ... |