2022-05-12 15:11:31 +03:00
|
|
|
package mtls
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/x509"
|
|
|
|
"math/big"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
// CertificateOptions holds options for x509.CreateCertificate
|
|
|
|
type CertificateOptions struct {
|
2024-12-09 16:23:25 +03:00
|
|
|
SerialNumber *big.Int
|
|
|
|
NotAfter time.Time
|
|
|
|
NotBefore time.Time
|
|
|
|
CommonName string
|
2022-05-12 15:11:31 +03:00
|
|
|
Organization []string
|
|
|
|
OrganizationalUnit []string
|
|
|
|
OCSPServer []string
|
|
|
|
IssuingCertificateURL []string
|
|
|
|
ExtKeyUsage []x509.ExtKeyUsage
|
2024-12-09 16:23:25 +03:00
|
|
|
|
|
|
|
SignatureAlgorithm x509.SignatureAlgorithm
|
|
|
|
PublicKeyAlgorithm x509.PublicKeyAlgorithm
|
|
|
|
KeyUsage x509.KeyUsage
|
|
|
|
IsCA bool
|
2022-05-12 15:11:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|