Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5307a0ce6d | ||
|
|
9d779377cf | ||
|
|
8f580defa0 | ||
|
|
a4d1237429 | ||
|
|
b8d8dae13d | ||
|
|
f5a2eabcab | ||
|
|
44ecf3af99 |
+6
-1
@@ -382,7 +382,12 @@ func testIssuance(t *testing.T, env *environment, challSrv challengeServer) {
|
|||||||
// Wait for the order to become ready for finalization.
|
// Wait for the order to become ready for finalization.
|
||||||
order, err = client.WaitOrder(ctx, order.URI)
|
order, err = client.WaitOrder(ctx, order.URI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to wait for order %s: %s", orderURL, err)
|
var orderErr *acme.OrderError
|
||||||
|
if errors.Is(err, orderErr) {
|
||||||
|
t.Fatalf("failed to wait for order %s: %s: %s", orderURL, err, orderErr.Problem)
|
||||||
|
} else {
|
||||||
|
t.Fatalf("failed to wait for order %s: %s", orderURL, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if order.Status != acme.StatusReady {
|
if order.Status != acme.StatusReady {
|
||||||
t.Fatalf("expected order %s status to be ready, got %v",
|
t.Fatalf("expected order %s status to be ready, got %v",
|
||||||
|
|||||||
+2
-2
@@ -272,7 +272,7 @@ func (c *Client) WaitOrder(ctx context.Context, url string) (*Order, error) {
|
|||||||
case err != nil:
|
case err != nil:
|
||||||
// Skip and retry.
|
// Skip and retry.
|
||||||
case o.Status == StatusInvalid:
|
case o.Status == StatusInvalid:
|
||||||
return nil, &OrderError{OrderURL: o.URI, Status: o.Status}
|
return nil, &OrderError{OrderURL: o.URI, Status: o.Status, Problem: o.Error}
|
||||||
case o.Status == StatusReady || o.Status == StatusValid:
|
case o.Status == StatusReady || o.Status == StatusValid:
|
||||||
return o, nil
|
return o, nil
|
||||||
}
|
}
|
||||||
@@ -369,7 +369,7 @@ func (c *Client) CreateOrderCert(ctx context.Context, url string, csr []byte, bu
|
|||||||
}
|
}
|
||||||
// The only acceptable status post finalize and WaitOrder is "valid".
|
// The only acceptable status post finalize and WaitOrder is "valid".
|
||||||
if o.Status != StatusValid {
|
if o.Status != StatusValid {
|
||||||
return nil, "", &OrderError{OrderURL: o.URI, Status: o.Status}
|
return nil, "", &OrderError{OrderURL: o.URI, Status: o.Status, Problem: o.Error}
|
||||||
}
|
}
|
||||||
crt, err := c.fetchCertRFC(ctx, o.CertURL, bundle)
|
crt, err := c.fetchCertRFC(ctx, o.CertURL, bundle)
|
||||||
return crt, o.CertURL, err
|
return crt, o.CertURL, err
|
||||||
|
|||||||
+16
-3
@@ -885,11 +885,17 @@ func TestRFC_WaitOrderError(t *testing.T) {
|
|||||||
s.handle("/orders/1", func(w http.ResponseWriter, r *http.Request) {
|
s.handle("/orders/1", func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Location", s.url("/orders/1"))
|
w.Header().Set("Location", s.url("/orders/1"))
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
s := StatusPending
|
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
s = StatusInvalid
|
// https://www.rfc-editor.org/rfc/rfc8555#section-7.3.3
|
||||||
|
errorData := `{
|
||||||
|
"type": "urn:ietf:params:acme:error:userActionRequired",
|
||||||
|
"detail": "Terms of service have changed",
|
||||||
|
"instance": "https://example.com/acme/agreement/?token=W8Ih3PswD-8"
|
||||||
|
}`
|
||||||
|
fmt.Fprintf(w, `{"status": %q, "error": %s}`, StatusInvalid, errorData)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(w, `{"status": %q}`, StatusPending)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, `{"status": %q}`, s)
|
|
||||||
count++
|
count++
|
||||||
})
|
})
|
||||||
s.start()
|
s.start()
|
||||||
@@ -910,6 +916,13 @@ func TestRFC_WaitOrderError(t *testing.T) {
|
|||||||
if e.Status != StatusInvalid {
|
if e.Status != StatusInvalid {
|
||||||
t.Errorf("e.Status = %q; want %q", e.Status, StatusInvalid)
|
t.Errorf("e.Status = %q; want %q", e.Status, StatusInvalid)
|
||||||
}
|
}
|
||||||
|
if e.Problem == nil {
|
||||||
|
t.Errorf("e.Problem = nil")
|
||||||
|
}
|
||||||
|
expectedProbType := "urn:ietf:params:acme:error:userActionRequired"
|
||||||
|
if e.Problem.ProblemType != expectedProbType {
|
||||||
|
t.Errorf("e.Problem.ProblemType = %q; want %q", e.Problem.ProblemType, expectedProbType)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRFC_CreateOrderCert(t *testing.T) {
|
func TestRFC_CreateOrderCert(t *testing.T) {
|
||||||
|
|||||||
+4
-1
@@ -154,13 +154,16 @@ func (a *AuthorizationError) Error() string {
|
|||||||
|
|
||||||
// OrderError is returned from Client's order related methods.
|
// OrderError is returned from Client's order related methods.
|
||||||
// It indicates the order is unusable and the clients should start over with
|
// It indicates the order is unusable and the clients should start over with
|
||||||
// AuthorizeOrder.
|
// AuthorizeOrder. A Problem description may be provided with details on
|
||||||
|
// what caused the order to become unusable.
|
||||||
//
|
//
|
||||||
// The clients can still fetch the order object from CA using GetOrder
|
// The clients can still fetch the order object from CA using GetOrder
|
||||||
// to inspect its state.
|
// to inspect its state.
|
||||||
type OrderError struct {
|
type OrderError struct {
|
||||||
OrderURL string
|
OrderURL string
|
||||||
Status string
|
Status string
|
||||||
|
// Problem is the error that occurred while processing the order.
|
||||||
|
Problem *Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (oe *OrderError) Error() string {
|
func (oe *OrderError) Error() string {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func ScalarBaseMult(dst, scalar *[32]byte) {
|
|||||||
curve := ecdh.X25519()
|
curve := ecdh.X25519()
|
||||||
priv, err := curve.NewPrivateKey(scalar[:])
|
priv, err := curve.NewPrivateKey(scalar[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("curve25519: internal error: scalarBaseMult was not 32 bytes")
|
panic("curve25519: " + err.Error())
|
||||||
}
|
}
|
||||||
copy(dst[:], priv.PublicKey().Bytes())
|
copy(dst[:], priv.PublicKey().Bytes())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
module golang.org/x/crypto
|
module golang.org/x/crypto
|
||||||
|
|
||||||
go 1.23.0
|
go 1.24.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
golang.org/x/net v0.42.0 // tagx:ignore
|
golang.org/x/net v0.43.0 // tagx:ignore
|
||||||
golang.org/x/sys v0.35.0
|
golang.org/x/sys v0.36.0
|
||||||
golang.org/x/term v0.34.0
|
golang.org/x/term v0.35.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require golang.org/x/text v0.28.0 // indirect
|
require golang.org/x/text v0.29.0 // indirect
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||||
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
||||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
|
||||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
|
||||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ var (
|
|||||||
// supportedKexAlgos specifies key-exchange algorithms implemented by this
|
// supportedKexAlgos specifies key-exchange algorithms implemented by this
|
||||||
// package in preference order, excluding those with security issues.
|
// package in preference order, excluding those with security issues.
|
||||||
supportedKexAlgos = []string{
|
supportedKexAlgos = []string{
|
||||||
|
KeyExchangeMLKEM768X25519,
|
||||||
KeyExchangeCurve25519,
|
KeyExchangeCurve25519,
|
||||||
KeyExchangeECDHP256,
|
KeyExchangeECDHP256,
|
||||||
KeyExchangeECDHP384,
|
KeyExchangeECDHP384,
|
||||||
@@ -94,6 +95,7 @@ var (
|
|||||||
// defaultKexAlgos specifies the default preference for key-exchange
|
// defaultKexAlgos specifies the default preference for key-exchange
|
||||||
// algorithms in preference order.
|
// algorithms in preference order.
|
||||||
defaultKexAlgos = []string{
|
defaultKexAlgos = []string{
|
||||||
|
KeyExchangeMLKEM768X25519,
|
||||||
KeyExchangeCurve25519,
|
KeyExchangeCurve25519,
|
||||||
KeyExchangeECDHP256,
|
KeyExchangeECDHP256,
|
||||||
KeyExchangeECDHP384,
|
KeyExchangeECDHP384,
|
||||||
|
|||||||
+15
-17
@@ -9,7 +9,6 @@ import (
|
|||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/subtle"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -439,6 +438,7 @@ func init() {
|
|||||||
kexAlgoMap[keyExchangeCurve25519LibSSH] = &curve25519sha256{}
|
kexAlgoMap[keyExchangeCurve25519LibSSH] = &curve25519sha256{}
|
||||||
kexAlgoMap[InsecureKeyExchangeDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1}
|
kexAlgoMap[InsecureKeyExchangeDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1}
|
||||||
kexAlgoMap[KeyExchangeDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256}
|
kexAlgoMap[KeyExchangeDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256}
|
||||||
|
kexAlgoMap[KeyExchangeMLKEM768X25519] = &mlkem768WithCurve25519sha256{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// curve25519sha256 implements the curve25519-sha256 (formerly known as
|
// curve25519sha256 implements the curve25519-sha256 (formerly known as
|
||||||
@@ -454,15 +454,17 @@ func (kp *curve25519KeyPair) generate(rand io.Reader) error {
|
|||||||
if _, err := io.ReadFull(rand, kp.priv[:]); err != nil {
|
if _, err := io.ReadFull(rand, kp.priv[:]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
curve25519.ScalarBaseMult(&kp.pub, &kp.priv)
|
p, err := curve25519.X25519(kp.priv[:], curve25519.Basepoint)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("curve25519: %w", err)
|
||||||
|
}
|
||||||
|
if len(p) != 32 {
|
||||||
|
return fmt.Errorf("curve25519: internal error: X25519 returned %d bytes, expected 32", len(p))
|
||||||
|
}
|
||||||
|
copy(kp.pub[:], p)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// curve25519Zeros is just an array of 32 zero bytes so that we have something
|
|
||||||
// convenient to compare against in order to reject curve25519 points with the
|
|
||||||
// wrong order.
|
|
||||||
var curve25519Zeros [32]byte
|
|
||||||
|
|
||||||
func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {
|
func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {
|
||||||
var kp curve25519KeyPair
|
var kp curve25519KeyPair
|
||||||
if err := kp.generate(rand); err != nil {
|
if err := kp.generate(rand); err != nil {
|
||||||
@@ -485,11 +487,9 @@ func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handsh
|
|||||||
return nil, errors.New("ssh: peer's curve25519 public value has wrong length")
|
return nil, errors.New("ssh: peer's curve25519 public value has wrong length")
|
||||||
}
|
}
|
||||||
|
|
||||||
var servPub, secret [32]byte
|
secret, err := curve25519.X25519(kp.priv[:], reply.EphemeralPubKey)
|
||||||
copy(servPub[:], reply.EphemeralPubKey)
|
if err != nil {
|
||||||
curve25519.ScalarMult(&secret, &kp.priv, &servPub)
|
return nil, fmt.Errorf("ssh: peer's curve25519 public value is not valid: %w", err)
|
||||||
if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 {
|
|
||||||
return nil, errors.New("ssh: peer's curve25519 public value has wrong order")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h := crypto.SHA256.New()
|
h := crypto.SHA256.New()
|
||||||
@@ -531,11 +531,9 @@ func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handsh
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var clientPub, secret [32]byte
|
secret, err := curve25519.X25519(kp.priv[:], kexInit.ClientPubKey)
|
||||||
copy(clientPub[:], kexInit.ClientPubKey)
|
if err != nil {
|
||||||
curve25519.ScalarMult(&secret, &kp.priv, &clientPub)
|
return nil, fmt.Errorf("ssh: peer's curve25519 public value is not valid: %w", err)
|
||||||
if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 {
|
|
||||||
return nil, errors.New("ssh: peer's curve25519 public value has wrong order")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hostKeyBytes := priv.PublicKey().Marshal()
|
hostKeyBytes := priv.PublicKey().Marshal()
|
||||||
|
|||||||
@@ -421,20 +421,26 @@ func New(files ...string) (ssh.HostKeyCallback, error) {
|
|||||||
return certChecker.CheckHostKey, nil
|
return certChecker.CheckHostKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize normalizes an address into the form used in known_hosts
|
// Normalize normalizes an address into the form used in known_hosts. Supports
|
||||||
|
// IPv4, hostnames, bracketed IPv6. Any other non-standard formats are returned
|
||||||
|
// with minimal transformation.
|
||||||
func Normalize(address string) string {
|
func Normalize(address string) string {
|
||||||
|
const defaultSSHPort = "22"
|
||||||
|
|
||||||
host, port, err := net.SplitHostPort(address)
|
host, port, err := net.SplitHostPort(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
host = address
|
host = address
|
||||||
port = "22"
|
port = defaultSSHPort
|
||||||
}
|
}
|
||||||
entry := host
|
|
||||||
if port != "22" {
|
if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
|
||||||
entry = "[" + entry + "]:" + port
|
host = host[1 : len(host)-1]
|
||||||
} else if strings.Contains(host, ":") && !strings.HasPrefix(host, "[") {
|
|
||||||
entry = "[" + entry + "]"
|
|
||||||
}
|
}
|
||||||
return entry
|
|
||||||
|
if port == defaultSSHPort {
|
||||||
|
return host
|
||||||
|
}
|
||||||
|
return "[" + host + "]:" + port
|
||||||
}
|
}
|
||||||
|
|
||||||
// Line returns a line to add append to the known_hosts files.
|
// Line returns a line to add append to the known_hosts files.
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ func TestLine(t *testing.T) {
|
|||||||
"server.org": "server.org " + edKeyStr,
|
"server.org": "server.org " + edKeyStr,
|
||||||
"server.org:22": "server.org " + edKeyStr,
|
"server.org:22": "server.org " + edKeyStr,
|
||||||
"server.org:23": "[server.org]:23 " + edKeyStr,
|
"server.org:23": "[server.org]:23 " + edKeyStr,
|
||||||
"[c629:1ec4:102:304:102:304:102:304]:22": "[c629:1ec4:102:304:102:304:102:304] " + edKeyStr,
|
"[c629:1ec4:102:304:102:304:102:304]:22": "c629:1ec4:102:304:102:304:102:304 " + edKeyStr,
|
||||||
"[c629:1ec4:102:304:102:304:102:304]:23": "[c629:1ec4:102:304:102:304:102:304]:23 " + edKeyStr,
|
"[c629:1ec4:102:304:102:304:102:304]:23": "[c629:1ec4:102:304:102:304:102:304]:23 " + edKeyStr,
|
||||||
} {
|
} {
|
||||||
if got := Line([]string{in}, edKey); got != want {
|
if got := Line([]string{in}, edKey); got != want {
|
||||||
@@ -310,14 +310,25 @@ func testHostHash(t *testing.T, hostname, encoded string) {
|
|||||||
|
|
||||||
func TestNormalize(t *testing.T) {
|
func TestNormalize(t *testing.T) {
|
||||||
for in, want := range map[string]string{
|
for in, want := range map[string]string{
|
||||||
"127.0.0.1:22": "127.0.0.1",
|
"127.0.0.1": "127.0.0.1",
|
||||||
"[127.0.0.1]:22": "127.0.0.1",
|
"127.0.0.1:22": "127.0.0.1",
|
||||||
"[127.0.0.1]:23": "[127.0.0.1]:23",
|
"[127.0.0.1]:22": "127.0.0.1",
|
||||||
"127.0.0.1:23": "[127.0.0.1]:23",
|
"[127.0.0.1]:23": "[127.0.0.1]:23",
|
||||||
"[a.b.c]:22": "a.b.c",
|
"127.0.0.1:23": "[127.0.0.1]:23",
|
||||||
"[abcd:abcd:abcd:abcd]": "[abcd:abcd:abcd:abcd]",
|
"[a.b.c]:22": "a.b.c",
|
||||||
"[abcd:abcd:abcd:abcd]:22": "[abcd:abcd:abcd:abcd]",
|
"[a.b.c]:23": "[a.b.c]:23",
|
||||||
"[abcd:abcd:abcd:abcd]:23": "[abcd:abcd:abcd:abcd]:23",
|
"abcd::abcd:abcd:abcd": "abcd::abcd:abcd:abcd",
|
||||||
|
"[abcd::abcd:abcd:abcd]": "abcd::abcd:abcd:abcd",
|
||||||
|
"[abcd::abcd:abcd:abcd]:22": "abcd::abcd:abcd:abcd",
|
||||||
|
"[abcd::abcd:abcd:abcd]:23": "[abcd::abcd:abcd:abcd]:23",
|
||||||
|
"2001:db8::1": "2001:db8::1",
|
||||||
|
"2001:db8::1:22": "2001:db8::1:22",
|
||||||
|
"[2001:db8::1]:22": "2001:db8::1",
|
||||||
|
"2001:db8::1:2200": "2001:db8::1:2200",
|
||||||
|
"a.b.c.d.com:2200": "[a.b.c.d.com]:2200",
|
||||||
|
"2001::db8:1": "2001::db8:1",
|
||||||
|
"2001::db8:1:22": "2001::db8:1:22",
|
||||||
|
"2001::db8:1:2200": "2001::db8:1:2200",
|
||||||
} {
|
} {
|
||||||
got := Normalize(in)
|
got := Normalize(in)
|
||||||
if got != want {
|
if got != want {
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build go1.24
|
|
||||||
|
|
||||||
package ssh
|
package ssh
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -13,23 +11,10 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"runtime"
|
|
||||||
"slices"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/curve25519"
|
"golang.org/x/crypto/curve25519"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
// After Go 1.24rc1 mlkem swapped the order of return values of Encapsulate.
|
|
||||||
// See #70950.
|
|
||||||
if runtime.Version() == "go1.24rc1" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
supportedKexAlgos = slices.Insert(supportedKexAlgos, 0, KeyExchangeMLKEM768X25519)
|
|
||||||
defaultKexAlgos = slices.Insert(defaultKexAlgos, 0, KeyExchangeMLKEM768X25519)
|
|
||||||
kexAlgoMap[KeyExchangeMLKEM768X25519] = &mlkem768WithCurve25519sha256{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mlkem768WithCurve25519sha256 implements the hybrid ML-KEM768 with
|
// mlkem768WithCurve25519sha256 implements the hybrid ML-KEM768 with
|
||||||
// curve25519-sha256 key exchange method, as described by
|
// curve25519-sha256 key exchange method, as described by
|
||||||
// draft-kampanakis-curdle-ssh-pq-ke-05 section 2.3.3.
|
// draft-kampanakis-curdle-ssh-pq-ke-05 section 2.3.3.
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
module golang.org/x/crypto/x509roots/fallback
|
module golang.org/x/crypto/x509roots/fallback
|
||||||
|
|
||||||
go 1.23.0
|
go 1.24.0
|
||||||
|
|||||||
Reference in New Issue
Block a user