<commit_before>package certinel

import (
	"crypto/tls"
	"crypto/x509"
	"encoding/base64"
	"encoding/json"
	"errors"
	"log"
	"strings"
	"time"

	"github.com/miekg/dns"
)

var (
	ErrNoPeerCertificate = errors.New("peer did not present certificate for domain")
	ErrExpired           = errors.New("certificate expired")
	ErrNotYetValid       = errors.New("certificate not yet valid")
	ErrInvalidHostname   = errors.New("invalid hostname")
	ErrNoCertificate     = errors.New("certificate serial not found")
)

type Domain struct {
	Domain string `json:"domain"`
	Port   string `json:"port"`
	cert   *x509.Certificate
}

type Status struct {
	Duration int64     `json:"check_duration"`
	Valid    bool      `json:"valid"`
	Err      string    `json:"error"`
	Time     time.Time `json:"last_check"`
}

type Subject struct {
	CommonName         string   `json:"cn"`
	Country            []string `json:"c"`
	Organization       []string `json:"o"`
	OrganizationalUnit []string `json:"ou"`
}

type Certificate struct {
	NotBefore      time.Time `json:"not_before"`
	NotAfter       time.Time `json:"not_after"`
	Issuer         Subject   `json:"issuer"`
	Subject        Subject   `json:"subject"`
	SerialNumber   string    `json:"serial"`
	AlternateNames []string  `json:"alternate_names"`
}

func convertCert(cert *x509.Certificate) *Certificate {
	result := &Certificate{
		NotBefore:      cert.NotBefore.UTC(),
		NotAfter:       cert.NotAfter.UTC(),
		SerialNumber:   cert.SerialNumber.String(),
		AlternateNames: cert.DNSNames,
	}

	result.Subject = Subject{
		CommonName:         cert.Subject.CommonName,
		Country:            cert.Subject.Country,
		Organization:       cert.Subject.Organization,
		OrganizationalUnit: cert.Subject.OrganizationalUnit,
	}

	result.Issuer = Subject{
		CommonName:         cert.Issuer.CommonName,
		Country:            cert.Issuer.Country,
		Organization:       cert.Issuer.Organization,
		OrganizationalUnit: cert.Issuer.OrganizationalUnit,
	}

	return result
}<commit_msg>more information in the certificate<commit_after>package certinel

import (
	"crypto/sha1"
	"crypto/sha256"
	"crypto/tls"
	"crypto/x509"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"errors"
	"log"
	"strings"
	"time"

	"github.com/miekg/dns"
)

var (
	ErrNoPeerCertificate = errors.New("peer did not present certificate for domain")
	ErrExpired           = errors.New("certificate expired")
	ErrNotYetValid       = errors.New("certificate not yet valid")
	ErrInvalidHostname   = errors.New("invalid hostname")
	ErrNoCertificate     = errors.New("certificate serial not found")
)

type Domain struct {
	Domain string `json:"domain"`
	Port   string `json:"port"`
	cert   *x509.Certificate
}

type Status struct {
	Duration int64     `json:"check_duration"`
	Valid    bool      `json:"valid"`
	Err      string    `json:"error"`
	Time     time.Time `json:"last_check"`
}

type Subject struct {
	CommonName         string   `json:"cn"`
	Country            []string `json:"c,omitempty"`
	Organization       []string `json:"o,omitempty"`
	OrganizationalUnit []string `json:"ou,omitempty"`
}

type Signature struct {
	Algorithm int    `json:"algorithm"`
	Value     string `json:"value"`
}

type Certificate struct {
	NotBefore      time.Time         `json:"not_before"`
	NotAfter       time.Time         `json:"not_after"`
	Issuer         Subject           `json:"issuer"`
	Subject        Subject           `json:"subject"`
	SerialNumber   string            `json:"serial"`
	AlternateNames []string          `json:"alternate_names,omitempty"`
	Signature      Signature         `json:"signature"`
	Fingerprints   map[string]string `json:"fingerprints"`
}

func toHexString(data []byte) string {
	result := make([]string, len(data))
	for i := 0; i < len(data); i += 1 {
		result[i] = hex.EncodeToString(data[i : i+1])
	}
	return strings.Join(result, ":")
}

func convertCert(cert *x509.Certificate) *Certificate {
	result := &Certificate{
		NotBefore:      cert.NotBefore.UTC(),
		NotAfter:       cert.NotAfter.UTC(),
		SerialNumber:   toHexString(cert.SerialNumber.Bytes()),
		AlternateNames: cert.DNSNames,
		Fingerprints:   make(map[string]string),
	}

	result.Signature = Signature{
		Value:     toHexString(cert.Signature),
		Algorithm: int(cert.SignatureAlgorithm),
	}

	result.Subject = Subject{
		CommonName:         cert.Subject.CommonName,
		Country:            cert.Subject.Country,
		Organization:       cert.Subject.Organization,
		OrganizationalUnit: cert.Subject.OrganizationalUnit,
	}

	result.Issuer = Subject{
		CommonName:         cert.Issuer.CommonName,
		Country:            cert.Issuer.Country,
		Organization:       cert.Issuer.Organization,
		OrganizationalUnit: cert.Issuer.OrganizationalUnit,
	}

	s256 := sha256.New()
	s256.Write(cert.Raw)
	result.Fingerprints["sha256"] = toHexString(s256.Sum(nil))

	s1 := sha1.New()
	s1.Write(cert.Raw)
	result.Fingerprints["sha1"] = toHexString(s1.Sum(nil))

	return result
}
{'fraction_non_alphanumeric': 0.12444264288609648, 'fraction_numerical': 0.010741791649777057, 'mean_word_length': 3.4660633484162897, 'pattern_counts': {'":': 1, '<': 4, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2676833', 'n_tokens_mistral': 1655, 'n_tokens_neox': 1564, 'n_words': 329}