// certSigAlgScan returns the server certificate with various sigature and hash algorithms in the ClientHello func certSigAlgsScan(addr, hostname string) (grade Grade, output Output, err error) { var certSigAlgs = make(map[string]string) for _, sigAlg := range tls.AllSignatureAndHashAlgorithms { _, _, derCerts, e := sayHello(addr, hostname, nil, nil, tls.VersionTLS12, []tls.SignatureAndHash{sigAlg}) if e == nil { if len(derCerts) == 0 { return Bad, nil, errors.New("no certs returned") } certs, _, err := helpers.ParseCertificatesDER(derCerts[0], "") if err != nil { return Bad, nil, err } certSigAlgs[sigAlg.String()] = helpers.SignatureString(certs[0].SignatureAlgorithm) //certSigAlgs = append(certSigAlgs, certs[0].SignatureAlgorithm) } } if len(certSigAlgs) > 0 { grade = Good output = certSigAlgs } else { err = errors.New("no SigAlgs supported") } return }
// certSigAlgScan returns the server certificate with various ciphers in the ClientHello func certSigAlgsScanByCipher(addr, hostname string) (grade Grade, output Output, err error) { var certSigAlgs = make(map[string]string) for cipherID := range tls.CipherSuites { _, _, derCerts, e := sayHello(addr, hostname, []uint16{cipherID}, nil, tls.VersionTLS12, []tls.SignatureAndHash{}) if e == nil { if len(derCerts) == 0 { return Bad, nil, errors.New("no certs returned") } certs, _, err := helpers.ParseCertificatesDER(derCerts[0], "") if err != nil { return Bad, nil, err } certSigAlgs[tls.CipherSuites[cipherID].Name] = helpers.SignatureString(certs[0].SignatureAlgorithm) //certSigAlgs = append(certSigAlgs, certs[0].SignatureAlgorithm) } } if len(certSigAlgs) > 0 { grade = Good output = certSigAlgs } else { err = errors.New("no cipher supported") } return }
// MarshalJSON serialises the bundle to JSON. The resulting JSON // structure contains the bundle (as a sequence of PEM-encoded // certificates), the certificate, the private key, the size of they // key, the issuer(s), the subject name(s), the expiration, the // hostname(s), the OCSP server, and the signature on the certificate. func (b *Bundle) MarshalJSON() ([]byte, error) { if b == nil || b.Cert == nil { return nil, errors.New("no certificate in bundle") } var keyBytes, rootBytes []byte var keyLength int var keyType, keyString string keyLength = helpers.KeyLength(b.Cert.PublicKey) switch b.Cert.PublicKeyAlgorithm { case x509.ECDSA: keyType = fmt.Sprintf("%d-bit ECDSA", keyLength) case x509.RSA: keyType = fmt.Sprintf("%d-bit RSA", keyLength) case x509.DSA: keyType = "DSA" default: keyType = "Unknown" } switch key := b.Key.(type) { case *rsa.PrivateKey: keyBytes = x509.MarshalPKCS1PrivateKey(key) keyString = PemBlockToString(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: keyBytes}) case *ecdsa.PrivateKey: keyBytes, _ = x509.MarshalECPrivateKey(key) keyString = PemBlockToString(&pem.Block{Type: "EC PRIVATE KEY", Bytes: keyBytes}) case fmt.Stringer: keyString = key.String() } if len(b.Hostnames) == 0 { b.buildHostnames() } var ocspSupport = false if b.Cert.OCSPServer != nil { ocspSupport = true } var crlSupport = false if b.Cert.CRLDistributionPoints != nil { crlSupport = true } if b.Root != nil { rootBytes = b.Root.Raw } return json.Marshal(map[string]interface{}{ "bundle": chain(b.Chain), "root": PemBlockToString(&pem.Block{Type: "CERTIFICATE", Bytes: rootBytes}), "crt": PemBlockToString(&pem.Block{Type: "CERTIFICATE", Bytes: b.Cert.Raw}), "key": keyString, "key_type": keyType, "key_size": keyLength, "issuer": names(b.Issuer.Names), "subject": names(b.Subject.Names), "expires": b.Expires, "hostnames": b.Hostnames, "ocsp_support": ocspSupport, "crl_support": crlSupport, "ocsp": b.Cert.OCSPServer, "signature": helpers.SignatureString(b.Cert.SignatureAlgorithm), "status": b.Status, }) }