mirror of
https://github.com/refraction-networking/utls.git
synced 2025-04-04 12:37:35 +03:00
crypto/tls: add support for Ed25519 certificates in TLS 1.2 and 1.3
Support for Ed25519 certificates was added in CL 175478, this wires them up into the TLS stack according to RFC 8422 (TLS 1.2) and RFC 8446 (TLS 1.3). RFC 8422 also specifies support for TLS 1.0 and 1.1, and I initially implemented that, but even OpenSSL doesn't take the complexity, so I just dropped it. It would have required keeping a buffer of the handshake transcript in order to do the direct Ed25519 signatures. We effectively need to support TLS 1.2 because it shares ClientHello signature algorithms with TLS 1.3. While at it, reordered the advertised signature algorithms in the rough order we would want to use them, also based on what curves have fast constant-time implementations. Client and client auth tests changed because of the change in advertised signature algorithms in ClientHello and CertificateRequest. Fixes #25355 Change-Id: I9fdd839afde4fd6b13fcbc5cc7017fd8c35085ee Reviewed-on: https://go-review.googlesource.com/c/go/+/177698 Run-TryBot: Filippo Valsorda <filippo@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
This commit is contained in:
parent
6c11745f0b
commit
28958b0da6
84 changed files with 4977 additions and 3938 deletions
|
@ -11,6 +11,7 @@ package main
|
|||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
|
@ -18,7 +19,6 @@ import (
|
|||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/big"
|
||||
"net"
|
||||
|
@ -34,6 +34,7 @@ var (
|
|||
isCA = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority")
|
||||
rsaBits = flag.Int("rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set")
|
||||
ecdsaCurve = flag.String("ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256 (recommended), P384, P521")
|
||||
ed25519Key = flag.Bool("ed25519", false, "Generate an Ed25519 key")
|
||||
)
|
||||
|
||||
func publicKey(priv interface{}) interface{} {
|
||||
|
@ -42,22 +43,8 @@ func publicKey(priv interface{}) interface{} {
|
|||
return &k.PublicKey
|
||||
case *ecdsa.PrivateKey:
|
||||
return &k.PublicKey
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func pemBlockForKey(priv interface{}) *pem.Block {
|
||||
switch k := priv.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
|
||||
case *ecdsa.PrivateKey:
|
||||
b, err := x509.MarshalECPrivateKey(k)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to marshal ECDSA private key: %v", err)
|
||||
os.Exit(2)
|
||||
}
|
||||
return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
|
||||
case ed25519.PrivateKey:
|
||||
return k.Public().(ed25519.PublicKey)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
@ -74,7 +61,11 @@ func main() {
|
|||
var err error
|
||||
switch *ecdsaCurve {
|
||||
case "":
|
||||
priv, err = rsa.GenerateKey(rand.Reader, *rsaBits)
|
||||
if *ed25519Key {
|
||||
_, priv, err = ed25519.GenerateKey(rand.Reader)
|
||||
} else {
|
||||
priv, err = rsa.GenerateKey(rand.Reader, *rsaBits)
|
||||
}
|
||||
case "P224":
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
|
||||
case "P256":
|
||||
|
@ -84,11 +75,10 @@ func main() {
|
|||
case "P521":
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "Unrecognized elliptic curve: %q", *ecdsaCurve)
|
||||
os.Exit(1)
|
||||
log.Fatalf("Unrecognized elliptic curve: %q", *ecdsaCurve)
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("failed to generate private key: %s", err)
|
||||
log.Fatalf("Failed to generate private key: %s", err)
|
||||
}
|
||||
|
||||
var notBefore time.Time
|
||||
|
@ -97,8 +87,7 @@ func main() {
|
|||
} else {
|
||||
notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err)
|
||||
os.Exit(1)
|
||||
log.Fatalf("Failed to parse creation date: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,7 +96,7 @@ func main() {
|
|||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to generate serial number: %s", err)
|
||||
log.Fatalf("Failed to generate serial number: %s", err)
|
||||
}
|
||||
|
||||
template := x509.Certificate{
|
||||
|
@ -144,26 +133,30 @@ func main() {
|
|||
|
||||
certOut, err := os.Create("cert.pem")
|
||||
if err != nil {
|
||||
log.Fatalf("failed to open cert.pem for writing: %s", err)
|
||||
log.Fatalf("Failed to open cert.pem for writing: %s", err)
|
||||
}
|
||||
if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
|
||||
log.Fatalf("failed to write data to cert.pem: %s", err)
|
||||
log.Fatalf("Failed to write data to cert.pem: %s", err)
|
||||
}
|
||||
if err := certOut.Close(); err != nil {
|
||||
log.Fatalf("error closing cert.pem: %s", err)
|
||||
log.Fatalf("Error closing cert.pem: %s", err)
|
||||
}
|
||||
log.Print("wrote cert.pem\n")
|
||||
|
||||
keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
log.Print("failed to open key.pem for writing:", err)
|
||||
log.Fatalf("Failed to open key.pem for writing:", err)
|
||||
return
|
||||
}
|
||||
if err := pem.Encode(keyOut, pemBlockForKey(priv)); err != nil {
|
||||
log.Fatalf("failed to write data to key.pem: %s", err)
|
||||
privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to marshal private key: %v", err)
|
||||
}
|
||||
if err := pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil {
|
||||
log.Fatalf("Failed to write data to key.pem: %s", err)
|
||||
}
|
||||
if err := keyOut.Close(); err != nil {
|
||||
log.Fatalf("error closing key.pem: %s", err)
|
||||
log.Fatalf("Error closing key.pem: %s", err)
|
||||
}
|
||||
log.Print("wrote key.pem\n")
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue