WACS-Kompatibilität
All checks were successful
release-tag / release-image (push) Successful in 1m47s
All checks were successful
release-tag / release-image (push) Successful in 1m47s
This commit is contained in:
49
main.go
49
main.go
@@ -420,45 +420,55 @@ type jwsPayload struct {
|
||||
JWK *jose.JSONWebKey
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// JWS verification helper – supports both JSON & compact JWS formats
|
||||
// -----------------------------------------------------------------------------
|
||||
func (s *server) verifyJWS(ctx context.Context, w http.ResponseWriter, r *http.Request) (*jwsPayload, bool) {
|
||||
if !jwsVerify {
|
||||
data, _ := io.ReadAll(r.Body)
|
||||
return &jwsPayload{Data: data}, true
|
||||
}
|
||||
|
||||
// Decode incoming JWS (JSON serialization expected)
|
||||
// read full body once
|
||||
raw, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, "read body", http.StatusBadRequest)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// try JWS JSON first …
|
||||
var sig jose.JSONWebSignature
|
||||
if err := json.NewDecoder(r.Body).Decode(&sig); err != nil {
|
||||
if err := json.Unmarshal(raw, &sig); err != nil || len(sig.Signatures) == 0 {
|
||||
// … fallback to compact serialization
|
||||
cp, err2 := jose.ParseSigned(string(raw))
|
||||
if err2 != nil {
|
||||
http.Error(w, "bad JWS", http.StatusBadRequest)
|
||||
return nil, false
|
||||
}
|
||||
if len(sig.Signatures) == 0 {
|
||||
http.Error(w, "no signature", http.StatusBadRequest)
|
||||
return nil, false
|
||||
sig = *cp
|
||||
}
|
||||
|
||||
prot := sig.Signatures[0].Protected // already decoded in go‑jose v3
|
||||
prot := sig.Signatures[0].Protected // already base-64 decoded
|
||||
|
||||
// Nonce replay‑protection
|
||||
// Nonce replay-protection
|
||||
if !s.db.takeNonce(ctx, prot.Nonce) {
|
||||
http.Error(w, "bad nonce", http.StatusForbidden)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Resolve verification key (inline JWK or referenced by kid)
|
||||
// Resolve verification key
|
||||
var key *jose.JSONWebKey
|
||||
if prot.JSONWebKey != nil {
|
||||
switch {
|
||||
case prot.JSONWebKey != nil:
|
||||
key = prot.JSONWebKey
|
||||
} else if prot.KeyID != "" {
|
||||
id := path.Base(prot.KeyID) // everything after last '/'
|
||||
k, err := s.db.accountKey(ctx, id)
|
||||
if err != nil {
|
||||
case prot.KeyID != "":
|
||||
if k, err := s.db.accountKey(ctx, path.Base(prot.KeyID)); err == nil {
|
||||
key = k
|
||||
} else {
|
||||
http.Error(w, "unknown kid", http.StatusUnauthorized)
|
||||
return nil, false
|
||||
}
|
||||
key = k
|
||||
}
|
||||
if key == nil {
|
||||
default:
|
||||
http.Error(w, "no verification key", http.StatusBadRequest)
|
||||
return nil, false
|
||||
}
|
||||
@@ -468,7 +478,6 @@ func (s *server) verifyJWS(ctx context.Context, w http.ResponseWriter, r *http.R
|
||||
http.Error(w, "signature invalid", http.StatusUnauthorized)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return &jwsPayload{Data: payload, JWK: key}, true
|
||||
}
|
||||
|
||||
@@ -489,6 +498,9 @@ func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Replay-Nonce", n)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
case r.Method == http.MethodGet && r.URL.Path == "/directory":
|
||||
s.handleDirectory(w, r)
|
||||
|
||||
case r.Method == http.MethodPost && r.URL.Path == "/acme/new-account":
|
||||
s.handleNewAccount(ctx, w, r)
|
||||
|
||||
@@ -501,9 +513,6 @@ func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
case r.Method == http.MethodPost && r.URL.Path == "/acme/revoke-cert":
|
||||
s.handleRevoke(ctx, w, r)
|
||||
|
||||
case r.Method == http.MethodGet && r.URL.Path == "/acme/directory":
|
||||
s.handleDirectory(w, r)
|
||||
|
||||
case r.Method == http.MethodGet && strings.HasPrefix(r.URL.Path, "/acme/order/"):
|
||||
s.handleGetOrder(ctx, w, r)
|
||||
|
||||
|
Reference in New Issue
Block a user