github.com/haraldrudell/parl@v0.4.176/parlca/selfsigned.go (about) 1 /* 2 © 2021–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package parlca 7 8 import ( 9 "crypto" 10 "crypto/rand" 11 "crypto/x509" 12 13 "github.com/haraldrudell/parl" 14 "github.com/haraldrudell/parl/perrors" 15 ) 16 17 const ( 18 /* 19 NoPassword PasswordType = "\tnoPassword" 20 GeneratePassword PasswordType = "\tgeneratePassword" 21 GenerateOnTheFly Strategy = iota << 0 22 UseFileSystem 23 DefaultStrategy = GenerateOnTheFly 24 */ 25 DefaultCountry = "US" // certificate country: US 26 notAfterYears = 10 // certificate validity for 10 years 27 caSubjectSuffix = "ca" // ca appended to commonName 28 ) 29 30 type SelfSigned struct { 31 parl.Certificate // DER() PEM() 32 PrivateKey parl.PrivateKey 33 } 34 35 func NewSelfSigned(canonicalName string, algo x509.PublicKeyAlgorithm) (ca parl.CertificateAuthority, err error) { 36 c := SelfSigned{} 37 38 // create private key 39 if c.PrivateKey, err = NewPrivateKey(algo); err != nil { 40 return 41 } 42 43 // create certificate of certificate authority 44 var certificateDer parl.CertificateDer 45 cert := &x509.Certificate{} 46 EnsureSelfSigned(cert) 47 if certificateDer, err = x509.CreateCertificate(rand.Reader, 48 cert, // template 49 cert, // parent 50 c.PrivateKey.Public(), // pub any: *rsa.PublicKey *ecdsa.PublicKey ed25519.PublicKey 51 c.PrivateKey, // priv any: crypto.Signer 52 ); perrors.IsPF(&err, "x509.CreateCertificate %w", err) { 53 return 54 } 55 c.Certificate = NewCertificate(certificateDer) 56 ca = &c 57 return 58 } 59 60 func NewSelfSigned2(privateKey parl.PrivateKey, certificate parl.Certificate) (ca parl.CertificateAuthority) { 61 return &SelfSigned{Certificate: certificate, PrivateKey: privateKey} 62 } 63 64 func (ca *SelfSigned) Sign(template *x509.Certificate, publicKey crypto.PublicKey) (certDER parl.CertificateDer, err error) { 65 66 // get certificate authority x509.Certificate 67 var caCert *x509.Certificate 68 if caCert, err = ca.Check(); err != nil { 69 return 70 } 71 caSigner := ca.PrivateKey //.Private() 72 73 // sign template 74 if certDER, err = x509.CreateCertificate(rand.Reader, template, caCert, publicKey, caSigner); err != nil { 75 err = perrors.Errorf("x509.CreateCertificate: '%w'", err) 76 return 77 } 78 return 79 } 80 81 func (ca *SelfSigned) Check() (cert *x509.Certificate, err error) { 82 if err = ca.PrivateKey.Validate(); err != nil { 83 return 84 } 85 if cert, err = ca.ParseCertificate(); perrors.IsPF(&err, "x509.ParseCertificate: '%w'", err) { 86 return 87 } 88 if cert.PublicKey == nil { 89 err = perrors.NewPF("public key uninitialied") 90 return 91 } 92 return 93 } 94 95 func (ca *SelfSigned) Private() (privateKey parl.PrivateKey) { 96 return ca.PrivateKey 97 }