mirror of
https://github.com/bettercap/bettercap
synced 2025-08-22 06:23:18 -07:00
1. Use better way to parse gateway on windows.
2. Fix untrusted cert on iOS 13 and up. 3. Allow to download cer/pem accessing to `mitm.it`.
This commit is contained in:
parent
c553b5ecb0
commit
331d56c406
8 changed files with 132 additions and 39 deletions
|
@ -24,6 +24,7 @@ type DNSSpoofer struct {
|
||||||
Hosts Hosts
|
Hosts Hosts
|
||||||
TTL uint32
|
TTL uint32
|
||||||
All bool
|
All bool
|
||||||
|
ResolveAll bool
|
||||||
waitGroup *sync.WaitGroup
|
waitGroup *sync.WaitGroup
|
||||||
pktSourceChan chan gopacket.Packet
|
pktSourceChan chan gopacket.Packet
|
||||||
}
|
}
|
||||||
|
@ -33,6 +34,7 @@ func NewDNSSpoofer(s *session.Session) *DNSSpoofer {
|
||||||
SessionModule: session.NewSessionModule("dns.spoof", s),
|
SessionModule: session.NewSessionModule("dns.spoof", s),
|
||||||
Handle: nil,
|
Handle: nil,
|
||||||
All: false,
|
All: false,
|
||||||
|
ResolveAll: true,
|
||||||
Hosts: Hosts{},
|
Hosts: Hosts{},
|
||||||
TTL: 1024,
|
TTL: 1024,
|
||||||
waitGroup: &sync.WaitGroup{},
|
waitGroup: &sync.WaitGroup{},
|
||||||
|
@ -64,6 +66,10 @@ func NewDNSSpoofer(s *session.Session) *DNSSpoofer {
|
||||||
"^[0-9]+$",
|
"^[0-9]+$",
|
||||||
"TTL of spoofed DNS replies."))
|
"TTL of spoofed DNS replies."))
|
||||||
|
|
||||||
|
mod.AddParam(session.NewBoolParameter("dns.spoof.resolve_all",
|
||||||
|
"true",
|
||||||
|
"If true the module will resolve every DNS request, even if it is not covered by spoof list."))
|
||||||
|
|
||||||
mod.AddHandler(session.NewModuleHandler("dns.spoof on", "",
|
mod.AddHandler(session.NewModuleHandler("dns.spoof on", "",
|
||||||
"Start the DNS spoofer in the background.",
|
"Start the DNS spoofer in the background.",
|
||||||
func(args []string) error {
|
func(args []string) error {
|
||||||
|
@ -106,6 +112,8 @@ func (mod *DNSSpoofer) Configure() error {
|
||||||
return err
|
return err
|
||||||
} else if err, mod.All = mod.BoolParam("dns.spoof.all"); err != nil {
|
} else if err, mod.All = mod.BoolParam("dns.spoof.all"); err != nil {
|
||||||
return err
|
return err
|
||||||
|
} else if err, mod.ResolveAll = mod.BoolParam("dns.spoof.resolve_all"); err != nil {
|
||||||
|
return err
|
||||||
} else if err, address = mod.IPParam("dns.spoof.address"); err != nil {
|
} else if err, address = mod.IPParam("dns.spoof.address"); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if err, domains = mod.ListParam("dns.spoof.domains"); err != nil {
|
} else if err, domains = mod.ListParam("dns.spoof.domains"); err != nil {
|
||||||
|
@ -287,6 +295,16 @@ func (mod *DNSSpoofer) onPacket(pkt gopacket.Packet) {
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
|
if mod.ResolveAll {
|
||||||
|
ips, err := net.LookupIP(qName)
|
||||||
|
if err == nil && len(ips) > 0 {
|
||||||
|
redir, who := DnsReply(mod.Session, mod.TTL, pkt, eth, udp, qName, ips[0], dns, eth.SrcMAC)
|
||||||
|
if redir != "" && who != "" {
|
||||||
|
mod.Info("sending forward DNS reply for %s %s to %s.", tui.Red(qName), tui.Dim(redir), tui.Bold(who))
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
mod.Debug("skipping domain %s", qName)
|
mod.Debug("skipping domain %s", qName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,7 +324,7 @@ func (mod *DNSSpoofer) Start() error {
|
||||||
src := gopacket.NewPacketSource(mod.Handle, mod.Handle.LinkType())
|
src := gopacket.NewPacketSource(mod.Handle, mod.Handle.LinkType())
|
||||||
mod.pktSourceChan = src.Packets()
|
mod.pktSourceChan = src.Packets()
|
||||||
for packet := range mod.pktSourceChan {
|
for packet := range mod.pktSourceChan {
|
||||||
if !mod.Running() {
|
if !mod.Running() || packet == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package http_proxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/bettercap/bettercap/session"
|
"github.com/bettercap/bettercap/session"
|
||||||
|
"github.com/evilsocket/islazy/fs"
|
||||||
|
|
||||||
"github.com/evilsocket/islazy/str"
|
"github.com/evilsocket/islazy/str"
|
||||||
)
|
)
|
||||||
|
@ -44,6 +45,11 @@ func NewHttpProxy(s *session.Session) *HttpProxy {
|
||||||
"",
|
"",
|
||||||
"URL, path or javascript code to inject into every HTML page."))
|
"URL, path or javascript code to inject into every HTML page."))
|
||||||
|
|
||||||
|
mod.AddParam(session.NewStringParameter("http.proxy.certificate",
|
||||||
|
"~/.bettercap-ca.cert.pem",
|
||||||
|
"",
|
||||||
|
"HTTP proxy certification authority TLS certificate file."))
|
||||||
|
|
||||||
mod.AddParam(session.NewStringParameter("http.proxy.blacklist", "", "",
|
mod.AddParam(session.NewStringParameter("http.proxy.blacklist", "", "",
|
||||||
"Comma separated list of hostnames to skip while proxying (wildcard expressions can be used)."))
|
"Comma separated list of hostnames to skip while proxying (wildcard expressions can be used)."))
|
||||||
|
|
||||||
|
@ -70,7 +76,7 @@ func NewHttpProxy(s *session.Session) *HttpProxy {
|
||||||
return mod.Stop()
|
return mod.Stop()
|
||||||
}))
|
}))
|
||||||
|
|
||||||
mod.InitState("stripper")
|
mod.InitState("stripper")
|
||||||
|
|
||||||
return mod
|
return mod
|
||||||
}
|
}
|
||||||
|
@ -94,6 +100,7 @@ func (mod *HttpProxy) Configure() error {
|
||||||
var httpPort int
|
var httpPort int
|
||||||
var doRedirect bool
|
var doRedirect bool
|
||||||
var scriptPath string
|
var scriptPath string
|
||||||
|
var certFile string
|
||||||
var stripSSL bool
|
var stripSSL bool
|
||||||
var useIDN bool
|
var useIDN bool
|
||||||
var jsToInject string
|
var jsToInject string
|
||||||
|
@ -118,6 +125,10 @@ func (mod *HttpProxy) Configure() error {
|
||||||
return err
|
return err
|
||||||
} else if err, jsToInject = mod.StringParam("http.proxy.injectjs"); err != nil {
|
} else if err, jsToInject = mod.StringParam("http.proxy.injectjs"); err != nil {
|
||||||
return err
|
return err
|
||||||
|
} else if err, certFile = mod.StringParam("http.proxy.certificate"); err != nil {
|
||||||
|
return err
|
||||||
|
} else if certFile, err = fs.Expand(certFile); err != nil {
|
||||||
|
return err
|
||||||
} else if err, blacklist = mod.StringParam("http.proxy.blacklist"); err != nil {
|
} else if err, blacklist = mod.StringParam("http.proxy.blacklist"); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if err, whitelist = mod.StringParam("http.proxy.whitelist"); err != nil {
|
} else if err, whitelist = mod.StringParam("http.proxy.whitelist"); err != nil {
|
||||||
|
@ -127,7 +138,7 @@ func (mod *HttpProxy) Configure() error {
|
||||||
mod.proxy.Blacklist = str.Comma(blacklist)
|
mod.proxy.Blacklist = str.Comma(blacklist)
|
||||||
mod.proxy.Whitelist = str.Comma(whitelist)
|
mod.proxy.Whitelist = str.Comma(whitelist)
|
||||||
|
|
||||||
error := mod.proxy.Configure(address, proxyPort, httpPort, doRedirect, scriptPath, jsToInject, stripSSL, useIDN)
|
error := mod.proxy.Configure(address, proxyPort, httpPort, doRedirect, scriptPath, jsToInject, stripSSL, useIDN, certFile)
|
||||||
|
|
||||||
// save stripper to share it with other http(s) proxies
|
// save stripper to share it with other http(s) proxies
|
||||||
mod.State.Store("stripper", mod.proxy.Stripper)
|
mod.State.Store("stripper", mod.proxy.Stripper)
|
||||||
|
|
|
@ -94,8 +94,13 @@ func NewHTTPProxy(s *session.Session, tag string) *HTTPProxy {
|
||||||
if !p.isTLS {
|
if !p.isTLS {
|
||||||
req.URL.Scheme = "http"
|
req.URL.Scheme = "http"
|
||||||
}
|
}
|
||||||
|
// Clone it.
|
||||||
req.URL.Host = req.Host
|
req.URL.Host = req.Host
|
||||||
p.Proxy.ServeHTTP(w, req)
|
if req.Host == "mitm.it" {
|
||||||
|
p.GetCert(w, req)
|
||||||
|
} else {
|
||||||
|
p.Proxy.ServeHTTP(w, req)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -106,6 +111,24 @@ func NewHTTPProxy(s *session.Session, tag string) *HTTPProxy {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *HTTPProxy) GetCert(w http.ResponseWriter, req *http.Request) {
|
||||||
|
if p.CertFile != "" {
|
||||||
|
respHeader := w.Header()
|
||||||
|
respHeader.Set("Content-Type", "application/x-x509-ca-cert")
|
||||||
|
if strings.Index(req.UserAgent(), "Windows NT") != -1 {
|
||||||
|
// Return cer certificate format.
|
||||||
|
respHeader.Set("Content-Disposition", "inline; filename=ca-cert.cer")
|
||||||
|
} else {
|
||||||
|
// Return pem certificate format.
|
||||||
|
respHeader.Set("Content-Disposition", "inline; filename=ca-cert.pem")
|
||||||
|
}
|
||||||
|
rawCert, _ := ioutil.ReadFile(p.CertFile)
|
||||||
|
_, _ = w.Write(rawCert)
|
||||||
|
} else {
|
||||||
|
http.NotFound(w, req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (p *HTTPProxy) Debug(format string, args ...interface{}) {
|
func (p *HTTPProxy) Debug(format string, args ...interface{}) {
|
||||||
p.Sess.Events.Log(log.DEBUG, p.tag+format, args...)
|
p.Sess.Events.Log(log.DEBUG, p.tag+format, args...)
|
||||||
}
|
}
|
||||||
|
@ -170,12 +193,12 @@ func (p *HTTPProxy) shouldProxy(req *http.Request) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *HTTPProxy) Configure(address string, proxyPort int, httpPort int, doRedirect bool, scriptPath string,
|
func (p *HTTPProxy) Configure(address string, proxyPort int, httpPort int, doRedirect bool, scriptPath string,
|
||||||
jsToInject string, stripSSL bool, useIDN bool) error {
|
jsToInject string, stripSSL bool, useIDN bool, certFile string) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// check if another http(s) proxy is using sslstrip and merge strippers
|
// check if another http(s) proxy is using sslstrip and merge strippers
|
||||||
if stripSSL {
|
if stripSSL {
|
||||||
for _, mname := range []string{"http.proxy", "https.proxy"}{
|
for _, mname := range []string{"http.proxy", "https.proxy"} {
|
||||||
err, m := p.Sess.Module(mname)
|
err, m := p.Sess.Module(mname)
|
||||||
if err == nil && m.Running() {
|
if err == nil && m.Running() {
|
||||||
var mextra interface{}
|
var mextra interface{}
|
||||||
|
@ -197,6 +220,8 @@ func (p *HTTPProxy) Configure(address string, proxyPort int, httpPort int, doRed
|
||||||
p.doRedirect = doRedirect
|
p.doRedirect = doRedirect
|
||||||
p.jsHook = ""
|
p.jsHook = ""
|
||||||
|
|
||||||
|
p.CertFile = certFile
|
||||||
|
|
||||||
if strings.HasPrefix(jsToInject, "http://") || strings.HasPrefix(jsToInject, "https://") {
|
if strings.HasPrefix(jsToInject, "http://") || strings.HasPrefix(jsToInject, "https://") {
|
||||||
p.jsHook = fmt.Sprintf("<script src=\"%s\" type=\"text/javascript\"></script></head>", jsToInject)
|
p.jsHook = fmt.Sprintf("<script src=\"%s\" type=\"text/javascript\"></script></head>", jsToInject)
|
||||||
} else if fs.Exists(jsToInject) {
|
} else if fs.Exists(jsToInject) {
|
||||||
|
@ -298,7 +323,7 @@ func (p *HTTPProxy) TLSConfigFromCA(ca *tls.Certificate) func(host string, ctx *
|
||||||
func (p *HTTPProxy) ConfigureTLS(address string, proxyPort int, httpPort int, doRedirect bool, scriptPath string,
|
func (p *HTTPProxy) ConfigureTLS(address string, proxyPort int, httpPort int, doRedirect bool, scriptPath string,
|
||||||
certFile string,
|
certFile string,
|
||||||
keyFile string, jsToInject string, stripSSL bool, useIDN bool) (err error) {
|
keyFile string, jsToInject string, stripSSL bool, useIDN bool) (err error) {
|
||||||
if err = p.Configure(address, proxyPort, httpPort, doRedirect, scriptPath, jsToInject, stripSSL, useIDN); err != nil {
|
if err = p.Configure(address, proxyPort, httpPort, doRedirect, scriptPath, jsToInject, stripSSL, useIDN, certFile); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -303,7 +303,7 @@ func SetInterfaceTxPower(name string, txpower int) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GatewayProvidedByUser(iface *Endpoint, gateway string) (*Endpoint, error) {
|
func GatewayProvidedByUser(iface *Endpoint, gateway string) (*Endpoint, error) {
|
||||||
Debug("GatewayProvidedByUser(%s) [cmd=%v opts=%v parser=%v]", gateway, IPv4RouteCmd, IPv4RouteCmdOpts, IPv4RouteParser)
|
Debug("GatewayProvidedByUser(%s) [cmd=%v opts=%v]", gateway, IPv4RouteCmd, IPv4RouteCmdOpts)
|
||||||
if IPv4Validator.MatchString(gateway) {
|
if IPv4Validator.MatchString(gateway) {
|
||||||
Debug("valid gateway ip %s", gateway)
|
Debug("valid gateway ip %s", gateway)
|
||||||
// we have the address, now we need its mac
|
// we have the address, now we need its mac
|
||||||
|
|
|
@ -3,17 +3,17 @@
|
||||||
package network
|
package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/bettercap/bettercap/core"
|
"github.com/bettercap/bettercap/core"
|
||||||
|
|
||||||
"github.com/evilsocket/islazy/str"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func FindGateway(iface *Endpoint) (*Endpoint, error) {
|
func FindGateway(iface *Endpoint) (*Endpoint, error) {
|
||||||
Debug("FindGateway(%s) [cmd=%v opts=%v parser=%v]", iface.Name(), IPv4RouteCmd, IPv4RouteCmdOpts, IPv4RouteParser)
|
Debug("FindGateway(%s) [cmd=%v opts=%v]", iface.Name(), IPv4RouteCmd, IPv4RouteCmdOpts)
|
||||||
|
|
||||||
output, err := core.Exec(IPv4RouteCmd, IPv4RouteCmdOpts)
|
output, err := core.ExecInEnglish(IPv4RouteCmd, append(IPv4RouteCmdOpts, fmt.Sprintf("%d", iface.Index)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("FindGateway(%s): core.Exec failed with %s", err)
|
Debug("FindGateway(%s): core.Exec failed with %s", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -22,25 +22,24 @@ func FindGateway(iface *Endpoint) (*Endpoint, error) {
|
||||||
Debug("FindGateway(%s) output:\n%s", iface.Name(), output)
|
Debug("FindGateway(%s) output:\n%s", iface.Name(), output)
|
||||||
|
|
||||||
ifName := iface.Name()
|
ifName := iface.Name()
|
||||||
for _, line := range strings.Split(output, "\n") {
|
scanner := bufio.NewScanner(strings.NewReader(output))
|
||||||
if line = str.Trim(line); strings.Contains(line, ifName) {
|
for scanner.Scan() {
|
||||||
m := IPv4RouteParser.FindStringSubmatch(line)
|
keyPair := strings.Split(scanner.Text(), ":")
|
||||||
if len(m) >= IPv4RouteTokens {
|
if len(keyPair) != 2 {
|
||||||
Debug("FindGateway(%s) line '%s' matched with %v", iface.Name(), line, m)
|
continue
|
||||||
return IPv4RouteIsGateway(ifName, m, func(gateway string) (*Endpoint, error) {
|
}
|
||||||
if gateway == iface.IpAddress {
|
key, value := strings.TrimSpace(keyPair[0]), strings.TrimSpace(keyPair[1])
|
||||||
Debug("gateway is the interface")
|
if key == "Default Gateway" {
|
||||||
return iface, nil
|
if value == iface.IpAddress {
|
||||||
} else {
|
return iface, nil
|
||||||
// we have the address, now we need its mac
|
} else {
|
||||||
mac, err := ArpLookup(ifName, gateway, false)
|
// we have the address, now we need its mac
|
||||||
if err != nil {
|
mac, err := ArpLookup(ifName, value, false)
|
||||||
return nil, err
|
if err != nil {
|
||||||
}
|
return nil, err
|
||||||
Debug("gateway is %s[%s]", gateway, mac)
|
}
|
||||||
return NewEndpoint(gateway, mac), nil
|
Debug("gateway is %s[%s]", value, mac)
|
||||||
}
|
return NewEndpoint(value, mac), nil
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,17 +3,14 @@ package network
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/google/gopacket/pcap"
|
"github.com/google/gopacket/pcap"
|
||||||
)
|
)
|
||||||
|
|
||||||
// only matches gateway lines
|
// only matches gateway lines
|
||||||
var IPv4RouteParser = regexp.MustCompile("^.+\\s+.+\\s+\\d+\\s+([0-9\\.]+/\\d+)\\s+\\d+\\s+([0-9\\.]+).*$")
|
|
||||||
var IPv4RouteTokens = 3
|
|
||||||
var IPv4RouteCmd = "netsh"
|
var IPv4RouteCmd = "netsh"
|
||||||
var IPv4RouteCmdOpts = []string{"interface", "ipv4", "show", "route"}
|
var IPv4RouteCmdOpts = []string{"interface", "ipv4", "show", "address"}
|
||||||
|
|
||||||
func IPv4RouteIsGateway(ifname string, tokens []string, f func(gateway string) (*Endpoint, error)) (*Endpoint, error) {
|
func IPv4RouteIsGateway(ifname string, tokens []string, f func(gateway string) (*Endpoint, error)) (*Endpoint, error) {
|
||||||
// TODO check if the subnet is the same as iface ?
|
// TODO check if the subnet is the same as iface ?
|
||||||
|
|
47
tls/cert.go
47
tls/cert.go
|
@ -3,8 +3,10 @@ package tls
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
|
"crypto/sha1"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"crypto/x509/pkix"
|
"crypto/x509/pkix"
|
||||||
|
"encoding/asn1"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
|
@ -74,6 +76,17 @@ func CertConfigFromModule(prefix string, m session.SessionModule) (cfg CertConfi
|
||||||
return cfg, err
|
return cfg, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
|
||||||
|
var oidNetscapeCertType = asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 1, 1}
|
||||||
|
|
||||||
|
var netscapeCetSSLCA = []byte{3, 2, 2, 4}
|
||||||
|
|
||||||
|
type publicKeyInfo struct {
|
||||||
|
Raw asn1.RawContent
|
||||||
|
Algorithm pkix.AlgorithmIdentifier
|
||||||
|
PublicKey asn1.BitString
|
||||||
|
}
|
||||||
|
|
||||||
func CreateCertificate(cfg CertConfig, ca bool) (*rsa.PrivateKey, []byte, error) {
|
func CreateCertificate(cfg CertConfig, ca bool) (*rsa.PrivateKey, []byte, error) {
|
||||||
priv, err := rsa.GenerateKey(rand.Reader, cfg.Bits)
|
priv, err := rsa.GenerateKey(rand.Reader, cfg.Bits)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -100,11 +113,41 @@ func CreateCertificate(cfg CertConfig, ca bool) (*rsa.PrivateKey, []byte, error)
|
||||||
},
|
},
|
||||||
NotBefore: notBefore,
|
NotBefore: notBefore,
|
||||||
NotAfter: notAfter,
|
NotAfter: notAfter,
|
||||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
|
||||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageEmailProtection, x509.ExtKeyUsageTimeStamping, x509.ExtKeyUsageMicrosoftCommercialCodeSigning, x509.ExtKeyUsageMicrosoftServerGatedCrypto, x509.ExtKeyUsageNetscapeServerGatedCrypto},
|
||||||
BasicConstraintsValid: true,
|
BasicConstraintsValid: true,
|
||||||
IsCA: ca,
|
IsCA: ca,
|
||||||
}
|
}
|
||||||
|
// We can only remove this once we move to go 1.15.
|
||||||
|
if ca && len(template.SubjectKeyId) == 0 {
|
||||||
|
// SubjectKeyId generated using method 1 in RFC 5280, Section 4.2.1.2
|
||||||
|
publicKeyBytes, err := asn1.Marshal(priv.PublicKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
// This is a NULL parameters value which is required by
|
||||||
|
// RFC 3279, Section 2.3.1.
|
||||||
|
publicKeyAlgorithm := pkix.AlgorithmIdentifier{
|
||||||
|
Algorithm: oidPublicKeyRSA,
|
||||||
|
Parameters: asn1.NullRawValue,
|
||||||
|
}
|
||||||
|
encodedPublicKey := asn1.BitString{BitLength: len(publicKeyBytes) * 8, Bytes: publicKeyBytes}
|
||||||
|
pki := publicKeyInfo{nil, publicKeyAlgorithm, encodedPublicKey}
|
||||||
|
b, err := asn1.Marshal(pki)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
h := sha1.Sum(b)
|
||||||
|
template.SubjectKeyId = h[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if ca {
|
||||||
|
template.ExtraExtensions = append(template.ExtraExtensions, pkix.Extension{
|
||||||
|
Id: oidNetscapeCertType,
|
||||||
|
Critical: false,
|
||||||
|
Value: netscapeCetSSLCA,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
cert, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
|
cert, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -63,7 +63,7 @@ func SignCertificateForHost(ca *tls.Certificate, host string, port int) (cert *t
|
||||||
},
|
},
|
||||||
NotBefore: notBefore,
|
NotBefore: notBefore,
|
||||||
NotAfter: notAfter,
|
NotAfter: notAfter,
|
||||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
||||||
BasicConstraintsValid: true,
|
BasicConstraintsValid: true,
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ func SignCertificateForHost(ca *tls.Certificate, host string, port int) (cert *t
|
||||||
}
|
}
|
||||||
|
|
||||||
var certpriv *rsa.PrivateKey
|
var certpriv *rsa.PrivateKey
|
||||||
if certpriv, err = rsa.GenerateKey(rand.Reader, 1024); err != nil {
|
if certpriv, err = rsa.GenerateKey(rand.Reader, 2048); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue