1.修改代码适配阿里云的服务器

This commit is contained in:
whm
2026-03-17 14:27:32 +08:00
parent 826617d737
commit 20e7f3a65d
1777 changed files with 775041 additions and 10 deletions

View File

@@ -0,0 +1,144 @@
// Copyright 2018 by David A. Golden. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
package scram
import (
"crypto/hmac"
"crypto/sha256"
"crypto/sha512"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"hash"
)
// ChannelBindingType represents the type of channel binding to use with
// SCRAM-PLUS authentication variants. The type must match one of the
// channel binding types defined in RFC 5056, RFC 5929, or RFC 9266.
type ChannelBindingType string
const (
// ChannelBindingNone indicates no channel binding is used.
ChannelBindingNone ChannelBindingType = ""
// ChannelBindingTLSUnique uses the TLS Finished message from the first
// TLS handshake (RFC 5929). This is considered insecure, but is included
// as required by RFC 5802.
ChannelBindingTLSUnique ChannelBindingType = "tls-unique"
// ChannelBindingTLSServerEndpoint uses a hash of the server's certificate
// (RFC 5929). This works with all TLS versions including TLS 1.3.
ChannelBindingTLSServerEndpoint ChannelBindingType = "tls-server-end-point"
// ChannelBindingTLSExporter uses TLS Exported Keying Material with the
// label "EXPORTER-Channel-Binding" (RFC 9266). This is the recommended
// channel binding type for TLS 1.3.
ChannelBindingTLSExporter ChannelBindingType = "tls-exporter"
)
// ChannelBinding holds the channel binding type and data for SCRAM-PLUS
// authentication. Use constructors to create type-specific bindings.
type ChannelBinding struct {
Type ChannelBindingType
Data []byte
}
// IsSupported returns true if the channel binding is configured with a
// non-empty type and data.
func (cb ChannelBinding) IsSupported() bool {
return cb.Type != ChannelBindingNone && len(cb.Data) > 0
}
// Matches returns true if this channel binding matches another channel
// binding in both type and data.
func (cb ChannelBinding) Matches(other ChannelBinding) bool {
if cb.Type != other.Type {
return false
}
return hmac.Equal(cb.Data, other.Data)
}
// NewTLSUniqueBinding creates a ChannelBinding for tls-unique channel binding.
// Since Go's standard library doesn't expose the TLS Finished message,
// applications must provide the data directly.
//
// Note: tls-unique is considered insecure and should generally be avoided.
func NewTLSUniqueBinding(data []byte) ChannelBinding {
// Create a defensive copy to prevent caller from modifying the data
cbData := make([]byte, len(data))
copy(cbData, data)
return ChannelBinding{
Type: ChannelBindingTLSUnique,
Data: cbData,
}
}
// NewTLSServerEndpointBinding creates a ChannelBinding for tls-server-end-point
// channel binding per RFC 5929. It extracts the server's certificate from
// the TLS connection state and hashes it using the appropriate hash function
// based on the certificate's signature algorithm.
//
// This works with all TLS versions including TLS 1.3.
func NewTLSServerEndpointBinding(connState *tls.ConnectionState) (ChannelBinding, error) {
if connState == nil {
return ChannelBinding{}, errors.New("connection state is nil")
}
if len(connState.PeerCertificates) == 0 {
return ChannelBinding{}, errors.New("no peer certificates")
}
cert := connState.PeerCertificates[0]
// Determine hash algorithm per RFC 5929
var h hash.Hash
switch cert.SignatureAlgorithm {
case x509.MD5WithRSA, x509.SHA1WithRSA, x509.DSAWithSHA1,
x509.ECDSAWithSHA1:
h = sha256.New() // Use SHA-256 for MD5/SHA-1
case x509.SHA256WithRSA, x509.SHA256WithRSAPSS,
x509.ECDSAWithSHA256:
h = sha256.New()
case x509.SHA384WithRSA, x509.SHA384WithRSAPSS,
x509.ECDSAWithSHA384:
h = sha512.New384()
case x509.SHA512WithRSA, x509.SHA512WithRSAPSS,
x509.ECDSAWithSHA512:
h = sha512.New()
default:
return ChannelBinding{}, fmt.Errorf("unsupported signature algorithm: %v",
cert.SignatureAlgorithm)
}
h.Write(cert.Raw)
return ChannelBinding{
Type: ChannelBindingTLSServerEndpoint,
Data: h.Sum(nil),
}, nil
}
// NewTLSExporterBinding creates a ChannelBinding for tls-exporter channel binding
// per RFC 9266. It uses TLS Exported Keying Material with the label
// "EXPORTER-Channel-Binding" and an empty context.
//
// This is the recommended channel binding type for TLS 1.3+.
func NewTLSExporterBinding(connState *tls.ConnectionState) (ChannelBinding, error) {
if connState == nil {
return ChannelBinding{}, errors.New("connection state is nil")
}
cbData, err := connState.ExportKeyingMaterial("EXPORTER-Channel-Binding", nil, 32)
if err != nil {
return ChannelBinding{}, fmt.Errorf("failed to export keying material: %w", err)
}
return ChannelBinding{
Type: ChannelBindingTLSExporter,
Data: cbData,
}, nil
}