Browse Source

Allow email SANs for S/MIME certificates (#152)

Ben Toews 6 years ago
parent
commit
0d4cf75db8
2 changed files with 16 additions and 3 deletions
  1. 10 1
      cert.go
  2. 6 2
      main.go

+ 10 - 1
cert.go

@@ -19,6 +19,7 @@ import (
 	"log"
 	"math/big"
 	"net"
+	"net/mail"
 	"os"
 	"os/user"
 	"path/filepath"
@@ -61,18 +62,26 @@ func (m *mkcert) makeCert(hosts []string) {
 		NotBefore: time.Now(),
 
 		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
-		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
 		BasicConstraintsValid: true,
 	}
+
 	for _, h := range hosts {
 		if ip := net.ParseIP(h); ip != nil {
 			tpl.IPAddresses = append(tpl.IPAddresses, ip)
+		} else if email, err := mail.ParseAddress(h); err == nil && email.Address == h {
+			tpl.EmailAddresses = append(tpl.EmailAddresses, h)
 		} else {
 			tpl.DNSNames = append(tpl.DNSNames, h)
 		}
 	}
+
 	if m.client {
 		tpl.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}
+	} else if len(tpl.IPAddresses) > 0 || len(tpl.DNSNames) > 0 {
+		tpl.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}
+	}
+	if len(tpl.EmailAddresses) > 0 {
+		tpl.ExtKeyUsage = append(tpl.ExtKeyUsage, x509.ExtKeyUsageCodeSigning, x509.ExtKeyUsageEmailProtection)
 	}
 
 	// IIS (the main target of PKCS #12 files), only shows the deprecated

+ 6 - 2
main.go

@@ -12,6 +12,7 @@ import (
 	"fmt"
 	"log"
 	"net"
+	"net/mail"
 	"os"
 	"path/filepath"
 	"regexp"
@@ -190,13 +191,16 @@ func (m *mkcert) Run(args []string) {
 		if ip := net.ParseIP(name); ip != nil {
 			continue
 		}
+		if email, err := mail.ParseAddress(name); err == nil && email.Address == name {
+			continue
+		}
 		punycode, err := idna.ToASCII(name)
 		if err != nil {
-			log.Fatalf("ERROR: %q is not a valid hostname or IP: %s", name, err)
+			log.Fatalf("ERROR: %q is not a valid hostname, IP, or email: %s", name, err)
 		}
 		args[i] = punycode
 		if !hostnameRegexp.MatchString(punycode) {
-			log.Fatalf("ERROR: %q is not a valid hostname or IP", name)
+			log.Fatalf("ERROR: %q is not a valid hostname, IP, or email", name)
 		}
 	}