crypto/tls 包中的自定义 VerifyPeerCertificate

Custom VerifyPeerCertificate in the crypto/tls package

我正在尝试编写自定义 VerifyPeerCertificate 以获取证书,即使 CN 和 FQDN 不匹配也是如此。

我是 golang 的新手,所以我正在尝试修改我找到的一些代码,并使其工作但没有成功。

这是我的代码:

package main

import (
    "fmt"
    "log"
    "crypto/tls"
    "crypto/x509"
)

func main() {

    customVerify := func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {

        roots := x509.NewCertPool()
        for _, rawCert := range rawCerts {
            c, _ := x509.ParseCertificate(rawCert)

            roots.AddCert(c)
        }
        cert, _ := x509.ParseCertificate(rawCerts[0])
        fmt.Println("subject name is : ",cert.Subject.CommonName)
        opts := x509.VerifyOptions{
            DNSName: cert.Subject.CommonName,
            Roots:   roots,
        }
        if _, err := cert.Verify(opts); err != nil {
            panic("failed to verify certificate: " + err.Error())
            return err
        }

        return nil
    }


    log.SetFlags(log.Lshortfile)

    conf := &tls.Config{
         InsecureSkipVerify: true,
         VerifyPeerCertificate: customVerify,
    }

    conn, err := tls.Dial("tcp", "127.0.0.1:9007", conf)


    if err != nil {

        log.Println(err)
        return
    }
    defer conn.Close()

    n, err := conn.Write([]byte("hello\n"))
    if err != nil {
        log.Println(n, err)
        return
    }

    buf := make([]byte, 100)
    n, err = conn.Read(buf)
    if err != nil {
        log.Println(n, err)
        return
    }

    println(string(buf[:n]))
}

我正在尝试获取本地服务器的证书。

当我尝试 运行 代码时,出现此错误:

root@mymachine:~/Tproject# go run test.go
subject name is :  dssdemo
test.go:50: remote error: tls: bad certificate

我试着模仿 example_Certificate_Verify

有人可以帮我解决这个问题吗?

提前谢谢你。

编辑:

相互 HTTPS 导致:test.go:50: remote error: tls: bad certificate 但是,是否有可能以某种方式 return 服务器证书?

此自定义验证忽略所有验证:

func ipSCert(host, port string) ([]*x509.Certificate, string, error) {
    var ipcertchain []*x509.Certificate

    customVerify := func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {

        roots := x509.NewCertPool()
        for _, rawCert := range rawCerts {

            c, _ := x509.ParseCertificate(rawCert)
            certItem, _ := x509.ParseCertificate(rawCert)
            ipcertchain = append(ipcertchain, certItem)
            roots.AddCert(c)

        }
        return nil
        
    }

    log.SetFlags(log.Lshortfile)

    d := &net.Dialer{
        Timeout: time.Duration(TimeoutSeconds) * time.Second,
    }

    cs, err := cipherSuite()
    if err != nil {
        return []*x509.Certificate{&x509.Certificate{}}, "", err
    }

    conf := &tls.Config{
        InsecureSkipVerify:    true,
        VerifyPeerCertificate: customVerify,
        CipherSuites:          cs,
        MaxVersion:            tlsVersion(),
    }

    conn, err := tls.DialWithDialer(d, "tcp", host+":"+port, conf)

    if err != nil {

        return nil, "", err
    }

    conn.Close()

    return ipcertchain, host, nil
}