I'm using x/crypto/pkcs12 to load a DER formatted *.p12 file. There is an example in the documentation that uses tls.X509KeyPair
to make a tls.Certificate
which can be used for an HTTP client.
That's perfect, and works fine. But then I also want to verify that the certificate hasn't expired. The pkcs12
library also has a Decode function which returns an x509 certificate, that I can than use the Verify method on. This also works fine.
It just seems odd to me that I'm decoding the DER twice. Once for an x509.Certificate
to verify, and again to get a tls.Certificate
. I don't know the relationship between these two Certificate structures, but seeing as the tls package has a function named tls.X509KeyPair that takes some bytes, shouldn't there also be an obvious way to get a tls.Certificate from an x509.Certificate or visa versa? What am I missing?
答案 0 :(得分:6)
tls.Certificate经常存储证书链 - 换句话说,> 1证书。请注意,其Certificate
字段的类型为[][]byte
,其中每个证书都是[]byte
。
tls包导入x509包,因此x509中没有函数来获取tls.Certificate;这将导致进口周期。但是如果你有x509.Certificate,你已经有了tls.Certificate;只需将x509.Certificate的Raw
字节放入tls.Certificate的Certificate
切片。
答案 1 :(得分:0)
你可以这样做:
func LoadP12TLSCfg(keystore, password string) (*x509.CertPool, tls.Certificate, error) {
data, err := ioutil.ReadFile(keystore)
if err != nil {
return nil, tls.Certificate{}, err
}
pk, crt, caCrts, err := pkcs12.DecodeChain(data, password)
if err != nil {
return nil, tls.Certificate{}, err
}
pool := x509.NewCertPool()
pool.AddCert(caCrts[0])
tlsCrt := tls.Certificate{
Certificate: [][]byte{crt.Raw},
Leaf: crt,
PrivateKey: pk,
}
return pool, tlsCrt, nil
}
func LoadServerTLSCfg(keystore, password string) (*tls.Config, error) {
pool, crt, err := LoadP12TLSCfg(keystore, password)
if err != nil {
return nil, err
}
cfg := &tls.Config{
ClientCAs: pool,
ClientAuth: tls.RequireAndVerifyClientCert,
Certificates: []tls.Certificate{crt},
}
return cfg, nil
}
func LoadClientTLSCfg(keystore, password string, serverName string) (*tls.Config, error) {
pool, crt, err := LoadP12TLSCfg(keystore, password)
if err != nil {
return nil, err
}
cfg := &tls.Config{
RootCAs: pool,
Certificates: []tls.Certificate{crt},
ServerName: serverName,
}
return cfg, nil
}