micro/mtls/options.go
Vasiliy Tolstov b8ad19a5a2 WIP: initial mtls package
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2022-05-12 15:11:31 +03:00

156 lines
4.3 KiB
Go

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
}