package mtls import ( "crypto/x509" "math/big" "time" ) // CertificateOptions holds options for x509.CreateCertificate type CertificateOptions struct { Organization []string OrganizationalUnit []string CommonName string OCSPServer []string IssuingCertificateURL []string SerialNumber *big.Int NotAfter time.Time NotBefore time.Time SignatureAlgorithm x509.SignatureAlgorithm PublicKeyAlgorithm x509.PublicKeyAlgorithm ExtKeyUsage []x509.ExtKeyUsage KeyUsage x509.KeyUsage IsCA bool } // CertificateOrganizationalUnit set OrganizationalUnit in certificate subject func CertificateOrganizationalUnit(s ...string) CertificateOption { return func(o *CertificateOptions) { o.OrganizationalUnit = s } } // CertificateOrganization set Organization in certificate subject func CertificateOrganization(s ...string) CertificateOption { return func(o *CertificateOptions) { o.Organization = s } } // CertificateCommonName set CommonName in certificate subject func CertificateCommonName(s string) CertificateOption { return func(o *CertificateOptions) { o.CommonName = s } } // CertificateOCSPServer set OCSPServer in certificate func CertificateOCSPServer(s ...string) CertificateOption { return func(o *CertificateOptions) { o.OCSPServer = s } } // CertificateIssuingCertificateURL set IssuingCertificateURL in certificate func CertificateIssuingCertificateURL(s ...string) CertificateOption { return func(o *CertificateOptions) { o.IssuingCertificateURL = s } } // CertificateSerialNumber set SerialNumber in certificate func CertificateSerialNumber(n *big.Int) CertificateOption { return func(o *CertificateOptions) { o.SerialNumber = n } } // CertificateNotAfter set NotAfter in certificate func CertificateNotAfter(t time.Time) CertificateOption { return func(o *CertificateOptions) { o.NotAfter = t } } // CertificateNotBefore set SerialNumber in certificate func CertificateNotBefore(t time.Time) CertificateOption { return func(o *CertificateOptions) { o.NotBefore = t } } // CertificateExtKeyUsage set ExtKeyUsage in certificate func CertificateExtKeyUsage(x ...x509.ExtKeyUsage) CertificateOption { return func(o *CertificateOptions) { o.ExtKeyUsage = x } } // CertificateSignatureAlgorithm set SignatureAlgorithm in certificate func CertificateSignatureAlgorithm(alg x509.SignatureAlgorithm) CertificateOption { return func(o *CertificateOptions) { o.SignatureAlgorithm = alg } } // CertificatePublicKeyAlgorithm set PublicKeyAlgorithm in certificate func CertificatePublicKeyAlgorithm(alg x509.PublicKeyAlgorithm) CertificateOption { return func(o *CertificateOptions) { o.PublicKeyAlgorithm = alg } } // CertificateKeyUsage set KeyUsage in certificate func CertificateKeyUsage(u x509.KeyUsage) CertificateOption { return func(o *CertificateOptions) { o.KeyUsage = u } } // CertificateIsCA set IsCA in certificate func CertificateIsCA(b bool) CertificateOption { return func(o *CertificateOptions) { o.IsCA = b } } // CertificateOption func signature type CertificateOption func(*CertificateOptions) func NewCertificateOptions(opts ...CertificateOption) CertificateOptions { options := CertificateOptions{} for _, o := range opts { o(&options) } if options.SerialNumber == nil { options.SerialNumber = big.NewInt(time.Now().UnixNano()) } if options.NotBefore.IsZero() { options.NotBefore = time.Now() } if options.NotAfter.IsZero() { options.NotAfter = time.Now().Add(10 * time.Minute) } if options.SignatureAlgorithm == x509.UnknownSignatureAlgorithm { options.SignatureAlgorithm = x509.PureEd25519 } if options.PublicKeyAlgorithm == x509.UnknownPublicKeyAlgorithm { options.PublicKeyAlgorithm = x509.Ed25519 } if options.ExtKeyUsage == nil { options.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth} if options.IsCA { options.ExtKeyUsage = append(options.ExtKeyUsage, x509.ExtKeyUsageOCSPSigning, x509.ExtKeyUsageTimeStamping) } } if options.KeyUsage == 0 { options.KeyUsage = x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature if options.IsCA { options.KeyUsage = x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageDataEncipherment | x509.KeyUsageCertSign } } return options }