-
-
Save cromefire/590eb9743dbadeca89c213b0aa1a2d58 to your computer and use it in GitHub Desktop.
go client cert error
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"crypto/ecdsa" | |
"crypto/elliptic" | |
"crypto/rand" | |
"crypto/rsa" | |
"crypto/tls" | |
"crypto/x509" | |
"crypto/x509/pkix" | |
"encoding/pem" | |
"fmt" | |
"math/big" | |
"net/http" | |
"os" | |
"time" | |
) | |
func publicKey(priv interface{}) interface{} { | |
switch k := priv.(type) { | |
case *rsa.PrivateKey: | |
return &k.PublicKey | |
case *ecdsa.PrivateKey: | |
return &k.PublicKey | |
default: | |
return nil | |
} | |
} | |
func pemBlockForKey(priv interface{}) (*pem.Block, error) { | |
switch k := priv.(type) { | |
case *rsa.PrivateKey: | |
return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}, nil | |
case *ecdsa.PrivateKey: | |
b, err := x509.MarshalECPrivateKey(k) | |
if err != nil { | |
return nil, err | |
} | |
return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}, nil | |
default: | |
return nil, fmt.Errorf("unknown key type") | |
} | |
} | |
// NewCertificateEcc generates and returns a new TLS certificate. | |
func NewCertificateEcc(commonName string) (tls.Certificate, error) { | |
priv, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("generate key: %s", err) | |
} | |
notBefore := time.Now() | |
notAfter := time.Date(2049, 12, 31, 23, 59, 59, 0, time.UTC) | |
template := x509.Certificate{ | |
SerialNumber: new(big.Int).SetInt64(123912838), | |
Subject: pkix.Name{ | |
CommonName: commonName, | |
}, | |
NotBefore: notBefore, | |
NotAfter: notAfter, | |
SignatureAlgorithm: x509.ECDSAWithSHA256, | |
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, | |
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, | |
BasicConstraintsValid: true, | |
} | |
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("create cert: %s", err) | |
} | |
certFile := "ecccert.pem" | |
certOut, err := os.Create(certFile) | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("save cert: %s", err) | |
} | |
err = pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("save cert: %s", err) | |
} | |
err = certOut.Close() | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("save cert: %s", err) | |
} | |
keyFile := "ecckey.pem" | |
keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("save key: %s", err) | |
} | |
block, err := pemBlockForKey(priv) | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("save key: %s", err) | |
} | |
err = pem.Encode(keyOut, block) | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("save key: %s", err) | |
} | |
err = keyOut.Close() | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("save key: %s", err) | |
} | |
return tls.LoadX509KeyPair(certFile, keyFile) | |
} | |
// NewCertificateRsa generates and returns a new TLS certificate. | |
func NewCertificateRsa(commonName string) (tls.Certificate, error) { | |
priv, err := rsa.GenerateKey(rand.Reader, 4092) | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("generate key: %s", err) | |
} | |
notBefore := time.Now() | |
notAfter := time.Date(2049, 12, 31, 23, 59, 59, 0, time.UTC) | |
template := x509.Certificate{ | |
SerialNumber: new(big.Int).SetInt64(123912838), | |
Subject: pkix.Name{ | |
CommonName: commonName, | |
}, | |
NotBefore: notBefore, | |
NotAfter: notAfter, | |
SignatureAlgorithm: x509.SHA384WithRSA, | |
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, | |
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, | |
BasicConstraintsValid: true, | |
} | |
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("create cert: %s", err) | |
} | |
certFile := "rsacert.pem" | |
certOut, err := os.Create(certFile) | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("save cert: %s", err) | |
} | |
err = pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("save cert: %s", err) | |
} | |
err = certOut.Close() | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("save cert: %s", err) | |
} | |
keyFile := "rsakey.pem" | |
keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("save key: %s", err) | |
} | |
block, err := pemBlockForKey(priv) | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("save key: %s", err) | |
} | |
err = pem.Encode(keyOut, block) | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("save key: %s", err) | |
} | |
err = keyOut.Close() | |
if err != nil { | |
return tls.Certificate{}, fmt.Errorf("save key: %s", err) | |
} | |
return tls.LoadX509KeyPair(certFile, keyFile) | |
} | |
func main() { | |
kl, err := os.OpenFile("/tmp/keylog.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) | |
if err != nil { | |
fmt.Printf("log: %s", err) | |
os.Exit(1) | |
} | |
_, err = fmt.Fprintf(kl, "# SSL/TLS secrets log file, generated by go\n") | |
if err != nil { | |
fmt.Printf("log: %s", err) | |
os.Exit(1) | |
} | |
fmt.Printf("Leaking TLS keys to /tmp/keylog.txt\n") | |
certEcc, err := NewCertificateEcc("test-client") | |
if err != nil { | |
fmt.Printf("client: %s", err) | |
os.Exit(1) | |
} | |
certRsa, err := NewCertificateRsa("test-client") | |
if err != nil { | |
fmt.Printf("client: %s", err) | |
os.Exit(1) | |
} | |
var rsaClient = &http.Client{ | |
Timeout: 5 * time.Minute, | |
Transport: &http.Transport{ | |
Proxy: http.ProxyFromEnvironment, | |
TLSClientConfig: &tls.Config{ | |
InsecureSkipVerify: true, | |
Certificates: []tls.Certificate{certRsa}, | |
KeyLogWriter: kl, | |
}, | |
}, | |
} | |
var eccClient = &http.Client{ | |
Timeout: 5 * time.Minute, | |
Transport: &http.Transport{ | |
Proxy: http.ProxyFromEnvironment, | |
TLSClientConfig: &tls.Config{ | |
InsecureSkipVerify: true, | |
Certificates: []tls.Certificate{certEcc}, | |
KeyLogWriter: kl, | |
}, | |
}, | |
} | |
var normalClient = &http.Client{ | |
Timeout: 5 * time.Minute, | |
Transport: &http.Transport{ | |
Proxy: http.ProxyFromEnvironment, | |
TLSClientConfig: &tls.Config{ | |
InsecureSkipVerify: true, | |
KeyLogWriter: kl, | |
}, | |
}, | |
} | |
_, err = rsaClient.Get("https://discovery.syncthing.net") | |
if err != nil { | |
fmt.Printf("rsa-ecc: %s\n", err) | |
} else { | |
fmt.Printf("rsa-ecc: ok\n") | |
} | |
_, err = eccClient.Get("https://discovery.syncthing.net") | |
if err != nil { | |
fmt.Printf("ecc-ecc: %s\n", err) | |
} else { | |
fmt.Printf("ecc-ecc: ok\n") | |
} | |
_, err = normalClient.Get("https://discovery.syncthing.net") | |
if err != nil { | |
fmt.Printf("nocert-ecc: %s\n", err) | |
} else { | |
fmt.Printf("nocert-ecc: ok\n") | |
} | |
_, err = rsaClient.Get("https://go-issue.cromefire.myds.me") | |
if err != nil { | |
fmt.Printf("rsa-rsa: %s\n", err) | |
} else { | |
fmt.Printf("rsa-rsa: ok\n") | |
} | |
_, err = eccClient.Get("https://go-issue.cromefire.myds.me") | |
if err != nil { | |
fmt.Printf("ecc-rsa: %s\n", err) | |
} else { | |
fmt.Printf("ecc-rsa: ok\n") | |
} | |
_, err = normalClient.Get("https://go-issue.cromefire.myds.me") | |
if err != nil { | |
fmt.Printf("nocert-rsa: %s\n", err) | |
} else { | |
fmt.Printf("nocert-rsa: ok\n") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment