github.com/daeuniverse/quic-go@v0.0.0-20240413031024-943f218e0810/integrationtests/tools/crypto.go (about) 1 package tools 2 3 import ( 4 "crypto" 5 "crypto/ed25519" 6 "crypto/rand" 7 "crypto/rsa" 8 "crypto/tls" 9 "crypto/x509" 10 "crypto/x509/pkix" 11 "math/big" 12 "net" 13 "time" 14 ) 15 16 const ALPN = "quic-go integration tests" 17 18 func GenerateCA() (*x509.Certificate, crypto.PrivateKey, error) { 19 certTempl := &x509.Certificate{ 20 SerialNumber: big.NewInt(2019), 21 Subject: pkix.Name{}, 22 NotBefore: time.Now(), 23 NotAfter: time.Now().Add(24 * time.Hour), 24 IsCA: true, 25 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, 26 KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, 27 BasicConstraintsValid: true, 28 } 29 pub, priv, err := ed25519.GenerateKey(rand.Reader) 30 if err != nil { 31 return nil, nil, err 32 } 33 caBytes, err := x509.CreateCertificate(rand.Reader, certTempl, certTempl, pub, priv) 34 if err != nil { 35 return nil, nil, err 36 } 37 ca, err := x509.ParseCertificate(caBytes) 38 if err != nil { 39 return nil, nil, err 40 } 41 return ca, priv, nil 42 } 43 44 func GenerateLeafCert(ca *x509.Certificate, caPriv crypto.PrivateKey) (*x509.Certificate, crypto.PrivateKey, error) { 45 certTempl := &x509.Certificate{ 46 SerialNumber: big.NewInt(1), 47 DNSNames: []string{"localhost"}, 48 IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1)}, 49 NotBefore: time.Now(), 50 NotAfter: time.Now().Add(24 * time.Hour), 51 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, 52 KeyUsage: x509.KeyUsageDigitalSignature, 53 } 54 pub, priv, err := ed25519.GenerateKey(rand.Reader) 55 if err != nil { 56 return nil, nil, err 57 } 58 certBytes, err := x509.CreateCertificate(rand.Reader, certTempl, ca, pub, caPriv) 59 if err != nil { 60 return nil, nil, err 61 } 62 cert, err := x509.ParseCertificate(certBytes) 63 if err != nil { 64 return nil, nil, err 65 } 66 return cert, priv, nil 67 } 68 69 // GenerateTLSConfigWithLongCertChain generates a tls.Config that uses a long certificate chain. 70 // The Root CA used is the same as for the config returned from getTLSConfig(). 71 func GenerateTLSConfigWithLongCertChain(ca *x509.Certificate, caPrivateKey crypto.PrivateKey) (*tls.Config, error) { 72 const chainLen = 7 73 certTempl := &x509.Certificate{ 74 SerialNumber: big.NewInt(2019), 75 Subject: pkix.Name{}, 76 NotBefore: time.Now(), 77 NotAfter: time.Now().Add(24 * time.Hour), 78 IsCA: true, 79 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, 80 KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, 81 BasicConstraintsValid: true, 82 } 83 84 lastCA := ca 85 lastCAPrivKey := caPrivateKey 86 privKey, err := rsa.GenerateKey(rand.Reader, 2048) 87 if err != nil { 88 return nil, err 89 } 90 certs := make([]*x509.Certificate, chainLen) 91 for i := 0; i < chainLen; i++ { 92 caBytes, err := x509.CreateCertificate(rand.Reader, certTempl, lastCA, &privKey.PublicKey, lastCAPrivKey) 93 if err != nil { 94 return nil, err 95 } 96 ca, err := x509.ParseCertificate(caBytes) 97 if err != nil { 98 return nil, err 99 } 100 certs[i] = ca 101 lastCA = ca 102 lastCAPrivKey = privKey 103 } 104 leafCert, leafPrivateKey, err := GenerateLeafCert(lastCA, lastCAPrivKey) 105 if err != nil { 106 return nil, err 107 } 108 109 rawCerts := make([][]byte, chainLen+1) 110 for i, cert := range certs { 111 rawCerts[chainLen-i] = cert.Raw 112 } 113 rawCerts[0] = leafCert.Raw 114 115 return &tls.Config{ 116 Certificates: []tls.Certificate{{ 117 Certificate: rawCerts, 118 PrivateKey: leafPrivateKey, 119 }}, 120 NextProtos: []string{ALPN}, 121 }, nil 122 }