go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/sdk/certutil/create_certificate_authority.go (about) 1 /* 2 3 Copyright (c) 2023 - Present. Will Charczuk. All rights reserved. 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository. 5 6 */ 7 8 package certutil 9 10 import ( 11 "crypto/rand" 12 "crypto/sha1" 13 "crypto/x509" 14 "crypto/x509/pkix" 15 "encoding/asn1" 16 "fmt" 17 18 "go.charczuk.com/sdk/errutil" 19 ) 20 21 // CreateCertificateAuthority creates a ca cert bundle from a given set of options. 22 // The cert bundle can be used to generate client and server certificates. 23 func CreateCertificateAuthority(options ...CertOption) (*CertBundle, error) { 24 createOptions := DefaultOptionsCertificateAuthority 25 26 if err := ResolveCertOptions(&createOptions, options...); err != nil { 27 return nil, err 28 } 29 if createOptions.PrivateKey == nil { 30 return nil, fmt.Errorf("create certificate authority; private key is unset") 31 } 32 var output CertBundle 33 output.PrivateKey = createOptions.PrivateKey 34 output.PublicKey = &createOptions.PrivateKey.PublicKey 35 36 var spki struct { 37 Algorithm pkix.AlgorithmIdentifier 38 SubjectPublicKey asn1.BitString 39 } 40 41 spkiASN1, err := x509.MarshalPKIXPublicKey(output.PublicKey) 42 if err != nil { 43 return nil, err 44 } 45 46 _, err = asn1.Unmarshal(spkiASN1, &spki) 47 if err != nil { 48 return nil, err 49 } 50 51 skid := sha1.Sum(spki.SubjectPublicKey.Bytes) 52 53 createOptions.SubjectKeyId = skid[:] 54 createOptions.BasicConstraintsValid = true 55 createOptions.IsCA = true 56 createOptions.MaxPathLenZero = true 57 58 der, err := x509.CreateCertificate(rand.Reader, &createOptions.Certificate, &createOptions.Certificate, output.PublicKey, output.PrivateKey) 59 if err != nil { 60 return nil, errutil.New(err) 61 } 62 cert, err := x509.ParseCertificate(der) 63 if err != nil { 64 return nil, errutil.New(err) 65 } 66 output.CertificateDERs = [][]byte{der} 67 output.Certificates = []x509.Certificate{*cert} 68 return &output, nil 69 }