Browse Source

调试签名校验接口

feature_gxh
Sydonian 4 months ago
parent
commit
72eecbe356
8 changed files with 97 additions and 38 deletions
  1. +1
    -0
      client/internal/http/auth/auth.go
  2. +2
    -5
      client/internal/http/types/config.go
  3. +33
    -0
      client/sdk/api/config.go
  4. +7
    -0
      client/sdk/api/v1/client.go
  5. +23
    -29
      client/sdk/api/v1/presigned.go
  6. +13
    -3
      client/sdk/api/v1/presigned_test.go
  7. +17
    -0
      client/sdk/signer/signer.go
  8. +1
    -1
      common/pkgs/storage/obs/obs_test.go

+ 1
- 0
client/internal/http/auth/auth.go View File

@@ -68,6 +68,7 @@ func (a *Auth) Presigned(c *gin.Context) {
c.AbortWithStatusJSON(401, types.Failed(ecode.Unauthorized, "client cert not found for access key id %s", accID))
return
}
c.Request.URL.Host = c.Request.Host

err := signer.VerifyPresigned(cliCert.VerifyKey, c.Request.Method, c.Request.URL)
if err != nil {


+ 2
- 5
client/internal/http/types/config.go View File

@@ -2,10 +2,8 @@ package types

import (
"crypto/ecdsa"
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"fmt"
"os"
@@ -74,9 +72,8 @@ func (c *ConfigJSON) Build() (Config, error) {
return Config{}, fmt.Errorf("invalid client cert %v: not an ECDSA public key", p)
}

pubKeyDer, _ := x509.MarshalPKIXPublicKey(pubKey)
pubHash := sha256.Sum256(pubKeyDer)
clientCerts[hex.EncodeToString(pubHash[:])] = &ClientCert{
accKeyID := signer.CalcAccessKeyIDFromPublicKey(pubKey)
clientCerts[accKeyID] = &ClientCert{
Cert: cert,
VerifyKey: signer.NewVerifyKey(pubKey),
}


+ 33
- 0
client/sdk/api/config.go View File

@@ -3,8 +3,41 @@ package api
import (
"crypto/tls"
"crypto/x509"
"fmt"
"os"
)

type ConfigJSON struct {
EndPoint string `json:"endpoint"`
RootCA string `json:"rootCA"`
ClientCert string `json:"clientCert"`
ClientKey string `json:"clientKey"`
}

func (c *ConfigJSON) Build() (Config, error) {
rootCAPool := x509.NewCertPool()

rootCAPem, err := os.ReadFile(c.RootCA)
if err != nil {
return Config{}, fmt.Errorf("reading root CA: %w", err)
}

if !rootCAPool.AppendCertsFromPEM(rootCAPem) {
return Config{}, fmt.Errorf("parsing root CA failed")
}

cliCert, err := tls.LoadX509KeyPair(c.ClientCert, c.ClientKey)
if err != nil {
return Config{}, fmt.Errorf("loading client cert: %w", err)
}

return Config{
EndPoint: c.EndPoint,
RootCA: rootCAPool,
Cert: cliCert,
}, nil
}

type Config struct {
EndPoint string
RootCA *x509.CertPool


+ 7
- 0
client/sdk/api/v1/client.go View File

@@ -1,12 +1,14 @@
package api

import (
"crypto/ecdsa"
"crypto/tls"
"net/http"

"gitlink.org.cn/cloudream/common/sdks"
"gitlink.org.cn/cloudream/jcs-pub/client/internal/http/auth"
"gitlink.org.cn/cloudream/jcs-pub/client/sdk/api"
"gitlink.org.cn/cloudream/jcs-pub/client/sdk/signer"
"golang.org/x/net/http2"
)

@@ -26,6 +28,7 @@ func (r *response[T]) ToError() *sdks.CodeMessageError {
type Client struct {
cfg api.Config
httpCli *http.Client
signKey *signer.SignKey
}

func NewClient(cfg api.Config) *Client {
@@ -39,8 +42,12 @@ func NewClient(cfg api.Config) *Client {
},
},
}

privKey := cfg.Cert.PrivateKey.(*ecdsa.PrivateKey)

return &Client{
cfg: cfg,
httpCli: httpCli,
signKey: signer.NewSignKey(privKey),
}
}

+ 23
- 29
client/sdk/api/v1/presigned.go View File

@@ -2,7 +2,11 @@ package api

import (
"net/http"
"net/url"
"time"

"github.com/google/go-querystring/query"
"gitlink.org.cn/cloudream/jcs-pub/client/sdk/signer"
clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types"
)

@@ -113,33 +117,23 @@ func (c *PresignedService) ObjectCompleteMultipartUpload(req PresignedObjectComp
}

func (c *PresignedService) presign(req any, path string, method string, expireIn int) (string, error) {
// u, err := url.Parse(c.cfg.EndPoint)
// if err != nil {
// return "", err
// }
// u = u.JoinPath(path)

// us, err := query.Values(req)
// if err != nil {
// return "", err
// }
// us.Add("X-Expires", fmt.Sprintf("%v", expireIn))

// u.RawQuery = us.Encode()

// prod := credentials.NewStaticCredentialsProvider(c.cfg.AccessKey, c.cfg.SecretKey, "")
// cred, err := prod.Retrieve(context.TODO())
// if err != nil {
// return "", err
// }

// r, err := http.NewRequest(method, u.String(), nil)
// if err != nil {
// return "", err
// }

// signer := v4.NewSigner()
// signedURL, _, err := signer.PresignHTTP(context.Background(), cred, r, "", AuthService, AuthRegion, time.Now())
// return signedURL, err
return "", nil
u, err := url.Parse(c.cfg.EndPoint)
if err != nil {
return "", err
}
u = u.JoinPath("/v1", path)

us, err := query.Values(req)
if err != nil {
return "", err
}

u.RawQuery = us.Encode()

err = signer.PresignURL(c.signKey, method, u, time.Now(), expireIn)
if err != nil {
return "", err
}

return u.String(), nil
}

+ 13
- 3
client/sdk/api/v1/presigned_test.go View File

@@ -9,9 +9,19 @@ import (
)

func Test_Presigned(t *testing.T) {
cli := NewClient(api.Config{
EndPoint: "http://localhost:7890",
})
cfg := api.ConfigJSON{
EndPoint: "https://localhost:7890",
RootCA: ``,
ClientCert: ``,
ClientKey: ``,
}

c, err := cfg.Build()
if err != nil {
panic(err)
}

cli := NewClient(c)

Convey("下载文件", t, func() {
pre := cli.Presigned()


+ 17
- 0
client/sdk/signer/signer.go View File

@@ -4,6 +4,7 @@ import (
"crypto/ecdsa"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
"encoding/hex"
"fmt"
"net/url"
@@ -33,6 +34,13 @@ type SignKey struct {
accessKeyID string
}

func NewSignKey(privKey *ecdsa.PrivateKey) *SignKey {
return &SignKey{
privateKey: privKey,
accessKeyID: CalcAccessKeyIDFromPublicKey(&privKey.PublicKey),
}
}

func PresignURL(key *SignKey, method string, u *url.URL, signingTime time.Time, expiresSeconds int) error {
date := signingTime.Format(DateFormat)

@@ -111,6 +119,12 @@ func VerifyPresigned(key *VerifyKey, method string, u *url.URL) error {
return nil
}

func CalcAccessKeyIDFromPublicKey(publicKey *ecdsa.PublicKey) string {
pubKeyDer, _ := x509.MarshalPKIXPublicKey(publicKey)
pubHash := sha256.Sum256(pubKeyDer)
return hex.EncodeToString(pubHash[:])
}

func makeStringToSign(method string, host string, path string, queries url.Values) string {
type queryKv struct {
Key string
@@ -132,6 +146,9 @@ func makeStringToSign(method string, host string, path string, queries url.Value
str.WriteByte('\n')
str.WriteString(host)
str.WriteByte('\n')
if !strings.HasPrefix(path, "/") {
str.WriteByte('/')
}
str.WriteString(path)
str.WriteByte('\n')
for _, kv := range queryKvs {


+ 1
- 1
common/pkgs/storage/obs/obs_test.go View File

@@ -33,7 +33,7 @@ func Test_S2S(t *testing.T) {
Bucket: "pcm2-bucket2",
ProjectID: "",
},
Credential: cortypes.OBSCred{
Credential: &cortypes.OBSCred{
AK: "",
SK: "",
},


Loading…
Cancel
Save