// 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
}
// 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

}
Exemple #3
0
// 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 typeString string
	var keyType 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"
	}
	if rsaKey, ok := b.Key.(*rsa.PrivateKey); ok {
		keyBytes = x509.MarshalPKCS1PrivateKey(rsaKey)
		typeString = "RSA PRIVATE KEY"
	} else if ecdsaKey, ok := b.Key.(*ecdsa.PrivateKey); ok {
		keyBytes, _ = x509.MarshalECPrivateKey(ecdsaKey)
		typeString = "EC PRIVATE KEY"
	}
	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":          PemBlockToString(&pem.Block{Type: typeString, Bytes: keyBytes}),
		"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,
	})
}
Exemple #4
0
// ParseCertificate parses an x509 certificate.
func ParseCertificate(cert *x509.Certificate) *Certificate {
	c := &Certificate{
		RawPEM:             string(helpers.EncodeCertificatePEM(cert)),
		SignatureAlgorithm: helpers.SignatureString(cert.SignatureAlgorithm),
		NotBefore:          cert.NotBefore,
		NotAfter:           cert.NotAfter,
		Subject:            ParseName(cert.Subject),
		SANs:               cert.DNSNames,
	}
	for _, ip := range cert.IPAddresses {
		c.SANs = append(c.SANs, ip.String())
	}
	return c
}
Exemple #5
0
// ParseCertificate parses an x509 certificate.
func ParseCertificate(cert *x509.Certificate) *Certificate {
	c := &Certificate{
		RawPEM:             string(helpers.EncodeCertificatePEM(cert)),
		SignatureAlgorithm: helpers.SignatureString(cert.SignatureAlgorithm),
		NotBefore:          cert.NotBefore,
		NotAfter:           cert.NotAfter,
		Subject:            ParseName(cert.Subject),
		Issuer:             ParseName(cert.Issuer),
		SANs:               cert.DNSNames,
		AKI:                formatKeyID(cert.AuthorityKeyId),
		SKI:                formatKeyID(cert.SubjectKeyId),
		SerialNumber:       cert.SerialNumber.String(),
	}
	for _, ip := range cert.IPAddresses {
		c.SANs = append(c.SANs, ip.String())
	}
	return c
}
Exemple #6
0
// Applies the naming convention of "commonname_issuedate_sigalg.crt" to all
// files by renaming them using helpers.ParseCertificatePEM
func applyNamingConv(file []byte, filename string) error {
	// Get the certificate info from helpers.ParseCertificatePEM
	response, err := helpers.ParseCertificatePEM(file)
	if err != nil {
		fmt.Println(err)
		return err
	}
	// Generate the name of the file
	name := ""
	// If CommonName field is empty, then use the Organization name instead
	if len(response.Subject.CommonName) == 0 {
		name = strings.Replace(response.Subject.Organization[0], " ", "", -1)
		name = strings.Replace(name, "/", "-", -1)
	} else {
		name = strings.Replace(response.Subject.CommonName, " ", "", -1)
		name = strings.Replace(name, "/", "-", -1)
	}
	dateIssued := fmt.Sprintf("%d-%d-%d", response.NotBefore.Year(),
		int(response.NotBefore.Month()),
		response.NotBefore.Day())
	name += "_" + dateIssued + "_" + helpers.SignatureString(response.SignatureAlgorithm)

	// If there is already a certificate of the same name, then add a count
	// at the end AKA, "commonname_issuedate_sigalg_2.crt" if there is
	// already a "commonname_issuedate_sigalg.crt", etc...
	filenameCount[name]++
	if filenameCount[name] > 1 {
		name += "_" + strconv.Itoa(filenameCount[name])
	}

	// Finally, rename the file
	err = os.Rename(*directory+"/"+filename, *directory+"/"+name+".crt")
	if err != nil {
		return err
	}
	return nil
}