func (tcc *TLSClientConfig) Verify(conn *tls.Conn) (*TLSState, error) { var ocsprep *ocsp.Response var der []byte var err error res := new(TLSState) cstate := conn.ConnectionState() res.SNIExist = (tcc.SNI != "") res.PKPExist = (tcc.PKPs != nil && len(tcc.PKPs) > 0) if cstate.OCSPResponse != nil { ocsprep, err = ocsp.ParseResponse(cstate.OCSPResponse, nil) if err != nil { return nil, err } res.OCSPExist = true res.OCSPValid = (ocsprep.Status == ocsp.Good) res.OCSPUnknown = (ocsprep.Status == ocsp.Unknown) } for _, peercert := range cstate.PeerCertificates { der, err = x509.MarshalPKIXPublicKey(peercert.PublicKey) if err != nil { return nil, err } if res.SNIExist && !res.SNIValid && peercert.VerifyHostname(tcc.SNI) == nil { res.SNIValid = true } if res.OCSPValid && !res.OCSPChecked && ocsprep.CheckSignatureFrom(peercert) == nil { res.OCSPChecked = true } rawhash := sha256.Sum256(der) hash := base64.StdEncoding.EncodeToString(rawhash[:]) if res.PKPExist { res.PKPCerts++ valid, ok := tcc.PKPs[hash] switch { case ok && valid: res.PKPValid++ case ok && !valid: res.PKPInvalid++ } } } return res, nil }
// TODO Security Issue : this code was audited 0 time func (db *HTTPDB) DialerTLS(network, addr string) (conn net.Conn, err error) { var ocsprep *ocsp.Response certok := false hostok := false ocspok := false c, err := tls.Dial(network, addr, db.tlsconfig) if err != nil { return c, err } cstate := c.ConnectionState() if cstate.OCSPResponse != nil { ocsprep, err = ocsp.ParseResponse(cstate.OCSPResponse, nil) if err != nil { return nil, err } switch ocsprep.Status { case ocsp.Good, ocsp.Unknown: default: return nil, errors.New(fmt.Sprintf("invalid OCSP")) } } for _, peercert := range cstate.PeerCertificates { der, err := x509.MarshalPKIXPublicKey(peercert.PublicKey) if err != nil { return nil, err } if !hostok && peercert.VerifyHostname(db.sni) == nil { hostok = true } if ocsprep != nil && !ocspok && ocsprep.CheckSignatureFrom(peercert) == nil { ocspok = true } rawhash := sha256.Sum256(der) hash := base64.StdEncoding.EncodeToString(rawhash[:]) if valid, ok := db.hpkp[hash]; !certok && ok && valid { certok = true } } if len(db.hpkp) > 0 && !certok { return nil, errors.New(fmt.Sprintf("invalid HPKP")) } if !hostok { return nil, errors.New(fmt.Sprintf("invalid SNI")) } if ocsprep != nil && !ocspok { return nil, errors.New(fmt.Sprintf("invalid OCSP")) } return c, nil }