在 go 语言中, Go 在发送 HTTP 请求后,在响应体中会包含一个 TLS *tls.ConnectionState 结构体,该结构体中目前存放了服务端返回的整个证书链:
// ConnectionState records basic TLS details about the connection.
typeConnectionStatestruct{// Version is the TLS version used by the connection (e.g. VersionTLS12).
Versionuint16// HandshakeComplete is true if the handshake has concluded.
HandshakeCompletebool// DidResume is true if this connection was successfully resumed from a
// previous session with a session ticket or similar mechanism.
DidResumebool// CipherSuite is the cipher suite negotiated for the connection (e.g.
// TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_AES_128_GCM_SHA256).
CipherSuiteuint16// NegotiatedProtocol is the application protocol negotiated with ALPN.
NegotiatedProtocolstring// NegotiatedProtocolIsMutual used to indicate a mutual NPN negotiation.
//// Deprecated: this value is always true.
NegotiatedProtocolIsMutualbool// ServerName is the value of the Server Name Indication extension sent by
// the client. It's available both on the server and on the client side.
ServerNamestring// PeerCertificates are the parsed certificates sent by the peer, in the
// order in which they were sent. The first element is the leaf certificate
// that the connection is verified against.
//// On the client side, it can't be empty. On the server side, it can be
// empty if Config.ClientAuth is not RequireAnyClientCert or
// RequireAndVerifyClientCert.
PeerCertificates[]*x509.Certificate// VerifiedChains is a list of one or more chains where the first element is
// PeerCertificates[0] and the last element is from Config.RootCAs (on the
// client side) or Config.ClientCAs (on the server side).
//// On the client side, it's set if Config.InsecureSkipVerify is false. On
// the server side, it's set if Config.ClientAuth is VerifyClientCertIfGiven
// (and the peer provided a certificate) or RequireAndVerifyClientCert.
VerifiedChains[][]*x509.Certificate// SignedCertificateTimestamps is a list of SCTs provided by the peer
// through the TLS handshake for the leaf certificate, if any.
SignedCertificateTimestamps[][]byte// OCSPResponse is a stapled Online Certificate Status Protocol (OCSP)
// response provided by the peer for the leaf certificate, if any.
OCSPResponse[]byte// TLSUnique contains the "tls-unique" channel binding value (see RFC 5929,
// Section 3). This value will be nil for TLS 1.3 connections and for all
// resumed connections.
//// Deprecated: there are conditions in which this value might not be unique
// to a connection. See the Security Considerations sections of RFC 5705 and
// RFC 7627, and https://mitls.org/pages/attacks/3SHAKE#channelbindings.
TLSUnique[]byte// ekm is a closure exposed via ExportKeyingMaterial.
ekmfunc(labelstring,context[]byte,lengthint)([]byte,error)}
// A Certificate represents an X.509 certificate.
typeCertificatestruct{Raw[]byte// Complete ASN.1 DER content (certificate, signature algorithm and signature).
RawTBSCertificate[]byte// Certificate part of raw ASN.1 DER content.
RawSubjectPublicKeyInfo[]byte// DER encoded SubjectPublicKeyInfo.
RawSubject[]byte// DER encoded Subject
RawIssuer[]byte// DER encoded Issuer
Signature[]byteSignatureAlgorithmSignatureAlgorithmPublicKeyAlgorithmPublicKeyAlgorithmPublicKeyinterface{}VersionintSerialNumber*big.IntIssuerpkix.NameSubjectpkix.NameNotBefore,NotAftertime.Time// Validity bounds.
KeyUsageKeyUsage// Extensions contains raw X.509 extensions. When parsing certificates,
// this can be used to extract non-critical extensions that are not
// parsed by this package. When marshaling certificates, the Extensions
// field is ignored, see ExtraExtensions.
Extensions[]pkix.Extension// ExtraExtensions contains extensions to be copied, raw, into any
// marshaled certificates. Values override any extensions that would
// otherwise be produced based on the other fields. The ExtraExtensions
// field is not populated when parsing certificates, see Extensions.
ExtraExtensions[]pkix.Extension// UnhandledCriticalExtensions contains a list of extension IDs that
// were not (fully) processed when parsing. Verify will fail if this
// slice is non-empty, unless verification is delegated to an OS
// library which understands all the critical extensions.
//// Users can access these extensions using Extensions and can remove
// elements from this slice if they believe that they have been
// handled.
UnhandledCriticalExtensions[]asn1.ObjectIdentifierExtKeyUsage[]ExtKeyUsage// Sequence of extended key usages.
UnknownExtKeyUsage[]asn1.ObjectIdentifier// Encountered extended key usages unknown to this package.
// BasicConstraintsValid indicates whether IsCA, MaxPathLen,
// and MaxPathLenZero are valid.
BasicConstraintsValidboolIsCAbool// MaxPathLen and MaxPathLenZero indicate the presence and
// value of the BasicConstraints' "pathLenConstraint".
//// When parsing a certificate, a positive non-zero MaxPathLen
// means that the field was specified, -1 means it was unset,
// and MaxPathLenZero being true mean that the field was
// explicitly set to zero. The case of MaxPathLen==0 with MaxPathLenZero==false
// should be treated equivalent to -1 (unset).
//// When generating a certificate, an unset pathLenConstraint
// can be requested with either MaxPathLen == -1 or using the
// zero value for both MaxPathLen and MaxPathLenZero.
MaxPathLenint// MaxPathLenZero indicates that BasicConstraintsValid==true
// and MaxPathLen==0 should be interpreted as an actual
// maximum path length of zero. Otherwise, that combination is
// interpreted as MaxPathLen not being set.
MaxPathLenZeroboolSubjectKeyId[]byteAuthorityKeyId[]byte// RFC 5280, 4.2.2.1 (Authority Information Access)
OCSPServer[]stringIssuingCertificateURL[]string// Subject Alternate Name values. (Note that these values may not be valid
// if invalid values were contained within a parsed certificate. For
// example, an element of DNSNames may not be a valid DNS domain name.)
DNSNames[]stringEmailAddresses[]stringIPAddresses[]net.IPURIs[]*url.URL// Name constraints
PermittedDNSDomainsCriticalbool// if true then the name constraints are marked critical.
PermittedDNSDomains[]stringExcludedDNSDomains[]stringPermittedIPRanges[]*net.IPNetExcludedIPRanges[]*net.IPNetPermittedEmailAddresses[]stringExcludedEmailAddresses[]stringPermittedURIDomains[]stringExcludedURIDomains[]string// CRL Distribution Points
CRLDistributionPoints[]stringPolicyIdentifiers[]asn1.ObjectIdentifier}