Чтобы выполнить аутентификацию сертификата клиента (взаимную аутентификацию), все примеры, которые я нашел, предполагают, что закрытый ключ доступен (например, из файла). Сертификат, содержащий закрытый и открытый ключ c, создается следующим образом:
cert, err := tls.LoadX509KeyPair("certs/client.pem", "certs/client.key")
Теперь я должен получить сертификат (и закрытый ключ, который, насколько я знаю, не может быть извлечен - подпись должно быть сделано через PKCS # 11) со смарт-карты. До сих пор мне удавалось перечислять сертификаты из хранилища сертификатов Windows:
store, err := syscall.UTF16PtrFromString("MY")
storeHandle, err := syscall.CertOpenSystemStore(0, store)
if err != nil {
fmt.Println(syscall.GetLastError())
}
var certs []*x509.Certificate
var cert *syscall.CertContext
for {
cert, err = syscall.CertEnumCertificatesInStore(storeHandle, cert)
if err != nil {
if errno, ok := err.(syscall.Errno); ok {
if errno == CRYPT_E_NOT_FOUND {
break
}
}
fmt.Println(syscall.GetLastError())
}
if cert == nil {
break
}
// Copy the buf, since ParseCertificate does not create its own copy.
buf := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:]
buf2 := make([]byte, cert.Length)
copy(buf2, buf)
if c, err := x509.ParseCertificate(buf2); err == nil {
for _, value := range c.ExtKeyUsage {
if value == x509.ExtKeyUsageClientAuth {
fmt.Println(c.Subject.CommonName)
fmt.Println(c.Issuer.CommonName)
certs = append(certs, c)
}
}
}
}
Этот сертификат, полученный таким образом, действительно получен со SmartCard. При последующем использовании аутентификации происходит сбой:
cer:= tls.Certificate{Certificate: [][]byte{certs[0].Raw}, Leaf: certs[0],}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cer},
RootCAs: caCertPool,
InsecureSkipVerify: true,
}
transport := &http.Transport{TLSClientConfig: tlsConfig}
client := http.Client{
Timeout: time.Minute * 2,
Transport: transport,
}
Я предполагаю, что сбоя следует ожидать, поскольку я не предоставил закрытый ключ.
Java (SunMSCAPI) и . NET кажется, что под обложками используется закрытый ключ на смарт-карте, например, я делаю то же самое, что и выше, и аутентификация "просто работает".
Есть ли способ добиться этого с помощью Go * * 1014