douya7121 2019-06-03 21:13
浏览 203
已采纳

从golang中传入的https请求中提取通用名称

My api is behind a gateway and the gateway terminates the ssl handshake from client and initiate a separate handshake with my api. No client should call my api directly. My requirement is that I have to extract the Common Name from incoming https request and validate it against a list.

I am new to go and used this example https://venilnoronha.io/a-step-by-step-guide-to-mtls-in-go as my starting point to build a go server using https.

But not sure how can I move further to to extract COMMON NAME from the leaf certificate of the certificate chain.

package main

import (
    "crypto/tls"
    "crypto/x509"
    "io"
    "io/ioutil"
    "log"
    "net/http"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
    // Write "Hello, world!" to the response body
    io.WriteString(w, "Hello, world!
")
}

func main() {
    // Set up a /hello resource handler
    http.HandleFunc("/hello", helloHandler)

    // Create a CA certificate pool and add cert.pem to it
    caCert, err := ioutil.ReadFile("cert.pem")
    if err != nil {
        log.Fatal(err)
    }
    caCertPool := x509.NewCertPool()
    caCertPool.AppendCertsFromPEM(caCert)

    // Create the TLS Config with the CA pool and enable Client certificate validation
    tlsConfig := &tls.Config{
        ClientCAs:  caCertPool,
        ClientAuth: tls.RequireAndVerifyClientCert,
    }
    tlsConfig.BuildNameToCertificate()

    // Create a Server instance to listen on port 8443 with the TLS config
    server := &http.Server{
        Addr:      ":8443",
        TLSConfig: tlsConfig,
    }

    // Listen to HTTPS connections with the server certificate and wait
    log.Fatal(server.ListenAndServeTLS("cert.pem", "key.pem"))

}

I should be able to print the Common Name of the leaf certificate coming in the certificate chain.

  • 写回答

1条回答 默认 最新

  • dpl22899 2019-06-03 21:23
    关注

    You can retrieve it from the VerifiedChains member of the request's TLS field:

    func helloHandler(w http.ResponseWriter, r *http.Request) {
        if r.TLS != nil && len(r.TLS.VerifiedChains) > 0 && len(r.TLS.VerifiedChains[0]) > 0 {
            var commonName = r.TLS.VerifiedChains[0][0].Subject.CommonName
    
            // Do what you want with the common name.
            io.WriteString(w, fmt.Sprintf("Hello, %s!
    ", commonName))
        }
    
        // Write "Hello, world!" to the response body
        io.WriteString(w, "Hello, world!
    ")
    }
    

    The leaf certificate is always the first one in the chain.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog