Add "Signature" for "auth-scheme"
このコミットが含まれているのは:
コミット
c86d639563
20
httpsig.go
20
httpsig.go
|
@ -72,6 +72,25 @@ const (
|
|||
Authorization SignatureScheme = "Authorization"
|
||||
)
|
||||
|
||||
const (
|
||||
// The HTTP Signatures specification uses the "Signature" auth-scheme
|
||||
// for the Authorization header. This is coincidentally named, but not
|
||||
// semantically the same, as the "Signature" HTTP header value.
|
||||
signatureAuthScheme = "Signature"
|
||||
)
|
||||
|
||||
// There are subtle differences to the values in the header. The Authorization
|
||||
// header has an 'auth-scheme' value that must be prefixed to the rest of the
|
||||
// key and values.
|
||||
func (s SignatureScheme) authScheme() string {
|
||||
switch s {
|
||||
case Authorization:
|
||||
return signatureAuthScheme
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// Signers will sign HTTP requests or responses based on the algorithms and
|
||||
// headers selected at creation time.
|
||||
//
|
||||
|
@ -175,6 +194,7 @@ func newSigner(algo Algorithm, headers []string, scheme SignatureScheme) (Signer
|
|||
s: s,
|
||||
headers: headers,
|
||||
targetHeader: scheme,
|
||||
prefix: scheme.authScheme(),
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
|
17
signing.go
17
signing.go
|
@ -17,6 +17,7 @@ const (
|
|||
algorithmParameter = "algorithm"
|
||||
headersParameter = "headers"
|
||||
signatureParameter = "signature"
|
||||
prefixSeparater = " "
|
||||
parameterKVSeparater = "="
|
||||
parameterValueDelimiter = "\""
|
||||
parameterSeparater = ","
|
||||
|
@ -41,6 +42,7 @@ type macSigner struct {
|
|||
m macer
|
||||
headers []string
|
||||
targetHeader SignatureScheme
|
||||
prefix string
|
||||
}
|
||||
|
||||
func (m *macSigner) SignRequest(pKey crypto.PrivateKey, pubKeyId string, r *http.Request) error {
|
||||
|
@ -52,7 +54,7 @@ func (m *macSigner) SignRequest(pKey crypto.PrivateKey, pubKeyId string, r *http
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
setSignatureHeader(r.Header, string(m.targetHeader), pubKeyId, m.m.String(), enc, m.headers)
|
||||
setSignatureHeader(r.Header, string(m.targetHeader), m.prefix, pubKeyId, m.m.String(), enc, m.headers)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -65,7 +67,7 @@ func (m *macSigner) SignResponse(pKey crypto.PrivateKey, pubKeyId string, r http
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
setSignatureHeader(r.Header(), string(m.targetHeader), pubKeyId, m.m.String(), enc, m.headers)
|
||||
setSignatureHeader(r.Header(), string(m.targetHeader), m.prefix, pubKeyId, m.m.String(), enc, m.headers)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -96,6 +98,7 @@ type asymmSigner struct {
|
|||
s signer
|
||||
headers []string
|
||||
targetHeader SignatureScheme
|
||||
prefix string
|
||||
}
|
||||
|
||||
func (a *asymmSigner) SignRequest(pKey crypto.PrivateKey, pubKeyId string, r *http.Request) error {
|
||||
|
@ -107,7 +110,7 @@ func (a *asymmSigner) SignRequest(pKey crypto.PrivateKey, pubKeyId string, r *ht
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
setSignatureHeader(r.Header, string(a.targetHeader), pubKeyId, a.s.String(), enc, a.headers)
|
||||
setSignatureHeader(r.Header, string(a.targetHeader), a.prefix, pubKeyId, a.s.String(), enc, a.headers)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -120,7 +123,7 @@ func (a *asymmSigner) SignResponse(pKey crypto.PrivateKey, pubKeyId string, r ht
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
setSignatureHeader(r.Header(), string(a.targetHeader), pubKeyId, a.s.String(), enc, a.headers)
|
||||
setSignatureHeader(r.Header(), string(a.targetHeader), a.prefix, pubKeyId, a.s.String(), enc, a.headers)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -141,12 +144,16 @@ func (a *asymmSigner) signatureStringResponse(r http.ResponseWriter) (string, er
|
|||
return signatureString(r.Header(), a.headers, requestTargetNotPermitted)
|
||||
}
|
||||
|
||||
func setSignatureHeader(h http.Header, targetHeader, pubKeyId, algo, enc string, headers []string) {
|
||||
func setSignatureHeader(h http.Header, targetHeader, prefix, pubKeyId, algo, enc string, headers []string) {
|
||||
if len(headers) == 0 {
|
||||
headers = defaultHeaders
|
||||
}
|
||||
var b bytes.Buffer
|
||||
// KeyId
|
||||
b.WriteString(prefix)
|
||||
if len(prefix) > 0 {
|
||||
b.WriteString(prefixSeparater)
|
||||
}
|
||||
b.WriteString(keyIdParameter)
|
||||
b.WriteString(parameterKVSeparater)
|
||||
b.WriteString(parameterValueDelimiter)
|
||||
|
|
25
verifying.go
25
verifying.go
|
@ -19,11 +19,11 @@ type verifier struct {
|
|||
}
|
||||
|
||||
func newVerifier(h http.Header, sigStringFn func(http.Header, []string) (string, error)) (*verifier, error) {
|
||||
s, err := getSignatureScheme(h)
|
||||
scheme, s, err := getSignatureScheme(h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kId, sig, headers, err := getSignatureComponents(s)
|
||||
kId, sig, headers, err := getSignatureComponents(scheme, s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ func (v *verifier) asymmVerify(s signer, pKey crypto.PublicKey) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getSignatureScheme(h http.Header) (string, error) {
|
||||
func getSignatureScheme(h http.Header) (scheme SignatureScheme, val string, err error) {
|
||||
s := h.Get(string(Signature))
|
||||
sigHasAll := strings.Contains(s, keyIdParameter) ||
|
||||
strings.Contains(s, headersParameter) ||
|
||||
|
@ -100,17 +100,26 @@ func getSignatureScheme(h http.Header) (string, error) {
|
|||
strings.Contains(a, headersParameter) ||
|
||||
strings.Contains(a, signatureParameter)
|
||||
if sigHasAll && authHasAll {
|
||||
return "", fmt.Errorf("both %q and %q have signature parameters", Signature, Authorization)
|
||||
err = fmt.Errorf("both %q and %q have signature parameters", Signature, Authorization)
|
||||
return
|
||||
} else if !sigHasAll && !authHasAll {
|
||||
return "", fmt.Errorf("neither %q nor %q have signature parameters", Signature, Authorization)
|
||||
err = fmt.Errorf("neither %q nor %q have signature parameters", Signature, Authorization)
|
||||
return
|
||||
} else if sigHasAll {
|
||||
return s, nil
|
||||
val = s
|
||||
scheme = Signature
|
||||
return
|
||||
} else { // authHasAll
|
||||
return a, nil
|
||||
val = a
|
||||
scheme = Authorization
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func getSignatureComponents(s string) (kId, sig string, headers []string, err error) {
|
||||
func getSignatureComponents(scheme SignatureScheme, s string) (kId, sig string, headers []string, err error) {
|
||||
if as := scheme.authScheme(); len(as) > 0 {
|
||||
s = strings.TrimPrefix(s, as+prefixSeparater)
|
||||
}
|
||||
params := strings.Split(s, parameterSeparater)
|
||||
for _, p := range params {
|
||||
kv := strings.SplitN(p, parameterKVSeparater, 2)
|
||||
|
|
読み込み中…
新しいイシューから参照