Updates #11776 Change-Id: I81756415feb630da093833accc3074903ebd84a7 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>main
parent
614c612643
commit
87546a5edf
@ -0,0 +1,97 @@ |
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package main |
||||
|
||||
import ( |
||||
"crypto/ecdsa" |
||||
"crypto/elliptic" |
||||
"crypto/rand" |
||||
"crypto/tls" |
||||
"crypto/x509" |
||||
"crypto/x509/pkix" |
||||
"encoding/pem" |
||||
"math/big" |
||||
"net" |
||||
"os" |
||||
"path/filepath" |
||||
"testing" |
||||
"time" |
||||
) |
||||
|
||||
// Verify that in --certmode=manual mode, we can use a bare IP address
|
||||
// as the --hostname and that GetCertificate will return it.
|
||||
func TestCertIP(t *testing.T) { |
||||
dir := t.TempDir() |
||||
const hostname = "1.2.3.4" |
||||
|
||||
priv, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader) |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) |
||||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
ip := net.ParseIP(hostname) |
||||
if ip == nil { |
||||
t.Fatalf("invalid IP address %q", hostname) |
||||
} |
||||
template := &x509.Certificate{ |
||||
SerialNumber: serialNumber, |
||||
Subject: pkix.Name{ |
||||
Organization: []string{"Tailscale Test Corp"}, |
||||
}, |
||||
NotBefore: time.Now(), |
||||
NotAfter: time.Now().Add(30 * 24 * time.Hour), |
||||
|
||||
KeyUsage: x509.KeyUsageDigitalSignature, |
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, |
||||
BasicConstraintsValid: true, |
||||
IPAddresses: []net.IP{ip}, |
||||
} |
||||
derBytes, err := x509.CreateCertificate(rand.Reader, template, template, &priv.PublicKey, priv) |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
certOut, err := os.Create(filepath.Join(dir, hostname+".crt")) |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { |
||||
t.Fatalf("Failed to write data to cert.pem: %v", err) |
||||
} |
||||
if err := certOut.Close(); err != nil { |
||||
t.Fatalf("Error closing cert.pem: %v", err) |
||||
} |
||||
|
||||
keyOut, err := os.OpenFile(filepath.Join(dir, hostname+".key"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
privBytes, err := x509.MarshalPKCS8PrivateKey(priv) |
||||
if err != nil { |
||||
t.Fatalf("Unable to marshal private key: %v", err) |
||||
} |
||||
if err := pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil { |
||||
t.Fatalf("Failed to write data to key.pem: %v", err) |
||||
} |
||||
if err := keyOut.Close(); err != nil { |
||||
t.Fatalf("Error closing key.pem: %v", err) |
||||
} |
||||
|
||||
cp, err := certProviderByCertMode("manual", dir, hostname) |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
back, err := cp.TLSConfig().GetCertificate(&tls.ClientHelloInfo{ |
||||
ServerName: "", // no SNI
|
||||
}) |
||||
if err != nil { |
||||
t.Fatalf("GetCertificate: %v", err) |
||||
} |
||||
if back == nil { |
||||
t.Fatalf("GetCertificate returned nil") |
||||
} |
||||
} |
||||
Loading…
Reference in new issue