12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- package main
- import (
- "crypto/rand"
- "crypto/rsa"
- "crypto/sha1"
- "crypto/x509"
- "crypto/x509/pkix"
- "encoding/asn1"
- "encoding/pem"
- "math/big"
- "os"
- "path/filepath"
- "testing"
- "time"
- "github.com/sagernet/sing/common/rw"
- "github.com/stretchr/testify/require"
- )
- func createSelfSignedCertificate(t *testing.T, domain string) (caPem, certPem, keyPem string) {
- const userAndHostname = "[email protected]"
- tempDir, err := os.MkdirTemp("", "sing-box-test")
- require.NoError(t, err)
- t.Cleanup(func() {
- os.RemoveAll(tempDir)
- })
- caKey, err := rsa.GenerateKey(rand.Reader, 3072)
- require.NoError(t, err)
- spkiASN1, err := x509.MarshalPKIXPublicKey(caKey.Public())
- var spki struct {
- Algorithm pkix.AlgorithmIdentifier
- SubjectPublicKey asn1.BitString
- }
- _, err = asn1.Unmarshal(spkiASN1, &spki)
- require.NoError(t, err)
- skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
- caTpl := &x509.Certificate{
- SerialNumber: randomSerialNumber(t),
- Subject: pkix.Name{
- Organization: []string{"sing-box test CA"},
- OrganizationalUnit: []string{userAndHostname},
- CommonName: "sing-box " + userAndHostname,
- },
- SubjectKeyId: skid[:],
- NotAfter: time.Now().AddDate(10, 0, 0),
- NotBefore: time.Now(),
- KeyUsage: x509.KeyUsageCertSign,
- BasicConstraintsValid: true,
- IsCA: true,
- MaxPathLenZero: true,
- }
- caCert, err := x509.CreateCertificate(rand.Reader, caTpl, caTpl, caKey.Public(), caKey)
- require.NoError(t, err)
- err = rw.WriteFile(filepath.Join(tempDir, "ca.pem"), pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: caCert}))
- require.NoError(t, err)
- key, err := rsa.GenerateKey(rand.Reader, 2048)
- domainTpl := &x509.Certificate{
- SerialNumber: randomSerialNumber(t),
- Subject: pkix.Name{
- Organization: []string{"sing-box test certificate"},
- OrganizationalUnit: []string{"sing-box " + userAndHostname},
- },
- NotBefore: time.Now(), NotAfter: time.Now().AddDate(0, 0, 30),
- KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
- ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
- }
- domainTpl.DNSNames = append(domainTpl.DNSNames, domain)
- cert, err := x509.CreateCertificate(rand.Reader, domainTpl, caTpl, key.Public(), caKey)
- require.NoError(t, err)
- certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert})
- privDER, err := x509.MarshalPKCS8PrivateKey(key)
- require.NoError(t, err)
- privPEM := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privDER})
- err = rw.WriteFile(filepath.Join(tempDir, domain+".pem"), certPEM)
- require.NoError(t, err)
- err = rw.WriteFile(filepath.Join(tempDir, domain+".key.pem"), privPEM)
- require.NoError(t, err)
- return filepath.Join(tempDir, "ca.pem"), filepath.Join(tempDir, domain+".pem"), filepath.Join(tempDir, domain+".key.pem")
- }
- func randomSerialNumber(t *testing.T) *big.Int {
- serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
- serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
- require.NoError(t, err)
- return serialNumber
- }
|