aboutsummaryrefslogtreecommitdiff
path: root/vendor/gopkg.in/square/go-jose.v2/signing.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gopkg.in/square/go-jose.v2/signing.go')
-rw-r--r--vendor/gopkg.in/square/go-jose.v2/signing.go343
1 files changed, 0 insertions, 343 deletions
diff --git a/vendor/gopkg.in/square/go-jose.v2/signing.go b/vendor/gopkg.in/square/go-jose.v2/signing.go
deleted file mode 100644
index 13e956d66..000000000
--- a/vendor/gopkg.in/square/go-jose.v2/signing.go
+++ /dev/null
@@ -1,343 +0,0 @@
-/*-
- * Copyright 2014 Square Inc.
- *
- * 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
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package jose
-
-import (
- "crypto/ecdsa"
- "crypto/rsa"
- "encoding/base64"
- "errors"
- "fmt"
-
- "golang.org/x/crypto/ed25519"
-
- "gopkg.in/square/go-jose.v2/json"
-)
-
-// NonceSource represents a source of random nonces to go into JWS objects
-type NonceSource interface {
- Nonce() (string, error)
-}
-
-// Signer represents a signer which takes a payload and produces a signed JWS object.
-type Signer interface {
- Sign(payload []byte) (*JSONWebSignature, error)
- Options() SignerOptions
-}
-
-// SigningKey represents an algorithm/key used to sign a message.
-type SigningKey struct {
- Algorithm SignatureAlgorithm
- Key interface{}
-}
-
-// SignerOptions represents options that can be set when creating signers.
-type SignerOptions struct {
- NonceSource NonceSource
- EmbedJWK bool
-
- // Optional map of additional keys to be inserted into the protected header
- // of a JWS object. Some specifications which make use of JWS like to insert
- // additional values here. All values must be JSON-serializable.
- ExtraHeaders map[HeaderKey]interface{}
-}
-
-// WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it
-// if necessary. It returns itself and so can be used in a fluent style.
-func (so *SignerOptions) WithHeader(k HeaderKey, v interface{}) *SignerOptions {
- if so.ExtraHeaders == nil {
- so.ExtraHeaders = map[HeaderKey]interface{}{}
- }
- so.ExtraHeaders[k] = v
- return so
-}
-
-// WithContentType adds a content type ("cty") header and returns the updated
-// SignerOptions.
-func (so *SignerOptions) WithContentType(contentType ContentType) *SignerOptions {
- return so.WithHeader(HeaderContentType, contentType)
-}
-
-// WithType adds a type ("typ") header and returns the updated SignerOptions.
-func (so *SignerOptions) WithType(typ ContentType) *SignerOptions {
- return so.WithHeader(HeaderType, typ)
-}
-
-type payloadSigner interface {
- signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error)
-}
-
-type payloadVerifier interface {
- verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error
-}
-
-type genericSigner struct {
- recipients []recipientSigInfo
- nonceSource NonceSource
- embedJWK bool
- extraHeaders map[HeaderKey]interface{}
-}
-
-type recipientSigInfo struct {
- sigAlg SignatureAlgorithm
- publicKey *JSONWebKey
- signer payloadSigner
-}
-
-// NewSigner creates an appropriate signer based on the key type
-func NewSigner(sig SigningKey, opts *SignerOptions) (Signer, error) {
- return NewMultiSigner([]SigningKey{sig}, opts)
-}
-
-// NewMultiSigner creates a signer for multiple recipients
-func NewMultiSigner(sigs []SigningKey, opts *SignerOptions) (Signer, error) {
- signer := &genericSigner{recipients: []recipientSigInfo{}}
-
- if opts != nil {
- signer.nonceSource = opts.NonceSource
- signer.embedJWK = opts.EmbedJWK
- signer.extraHeaders = opts.ExtraHeaders
- }
-
- for _, sig := range sigs {
- err := signer.addRecipient(sig.Algorithm, sig.Key)
- if err != nil {
- return nil, err
- }
- }
-
- return signer, nil
-}
-
-// newVerifier creates a verifier based on the key type
-func newVerifier(verificationKey interface{}) (payloadVerifier, error) {
- switch verificationKey := verificationKey.(type) {
- case ed25519.PublicKey:
- return &edEncrypterVerifier{
- publicKey: verificationKey,
- }, nil
- case *rsa.PublicKey:
- return &rsaEncrypterVerifier{
- publicKey: verificationKey,
- }, nil
- case *ecdsa.PublicKey:
- return &ecEncrypterVerifier{
- publicKey: verificationKey,
- }, nil
- case []byte:
- return &symmetricMac{
- key: verificationKey,
- }, nil
- case JSONWebKey:
- return newVerifier(verificationKey.Key)
- case *JSONWebKey:
- return newVerifier(verificationKey.Key)
- default:
- return nil, ErrUnsupportedKeyType
- }
-}
-
-func (ctx *genericSigner) addRecipient(alg SignatureAlgorithm, signingKey interface{}) error {
- recipient, err := makeJWSRecipient(alg, signingKey)
- if err != nil {
- return err
- }
-
- ctx.recipients = append(ctx.recipients, recipient)
- return nil
-}
-
-func makeJWSRecipient(alg SignatureAlgorithm, signingKey interface{}) (recipientSigInfo, error) {
- switch signingKey := signingKey.(type) {
- case ed25519.PrivateKey:
- return newEd25519Signer(alg, signingKey)
- case *rsa.PrivateKey:
- return newRSASigner(alg, signingKey)
- case *ecdsa.PrivateKey:
- return newECDSASigner(alg, signingKey)
- case []byte:
- return newSymmetricSigner(alg, signingKey)
- case JSONWebKey:
- return newJWKSigner(alg, signingKey)
- case *JSONWebKey:
- return newJWKSigner(alg, *signingKey)
- default:
- return recipientSigInfo{}, ErrUnsupportedKeyType
- }
-}
-
-func newJWKSigner(alg SignatureAlgorithm, signingKey JSONWebKey) (recipientSigInfo, error) {
- recipient, err := makeJWSRecipient(alg, signingKey.Key)
- if err != nil {
- return recipientSigInfo{}, err
- }
- if recipient.publicKey != nil {
- // recipient.publicKey is a JWK synthesized for embedding when recipientSigInfo
- // was created for the inner key (such as a RSA or ECDSA public key). It contains
- // the pub key for embedding, but doesn't have extra params like key id.
- publicKey := signingKey
- publicKey.Key = recipient.publicKey.Key
- recipient.publicKey = &publicKey
-
- // This should be impossible, but let's check anyway.
- if !recipient.publicKey.IsPublic() {
- return recipientSigInfo{}, errors.New("square/go-jose: public key was unexpectedly not public")
- }
- }
- return recipient, nil
-}
-
-func (ctx *genericSigner) Sign(payload []byte) (*JSONWebSignature, error) {
- obj := &JSONWebSignature{}
- obj.payload = payload
- obj.Signatures = make([]Signature, len(ctx.recipients))
-
- for i, recipient := range ctx.recipients {
- protected := map[HeaderKey]interface{}{
- headerAlgorithm: string(recipient.sigAlg),
- }
-
- if recipient.publicKey != nil {
- // We want to embed the JWK or set the kid header, but not both. Having a protected
- // header that contains an embedded JWK while also simultaneously containing the kid
- // header is confusing, and at least in ACME the two are considered to be mutually
- // exclusive. The fact that both can exist at the same time is a somewhat unfortunate
- // result of the JOSE spec. We've decided that this library will only include one or
- // the other to avoid this confusion.
- //
- // See https://github.com/square/go-jose/issues/157 for more context.
- if ctx.embedJWK {
- protected[headerJWK] = recipient.publicKey
- } else {
- protected[headerKeyID] = recipient.publicKey.KeyID
- }
- }
-
- if ctx.nonceSource != nil {
- nonce, err := ctx.nonceSource.Nonce()
- if err != nil {
- return nil, fmt.Errorf("square/go-jose: Error generating nonce: %v", err)
- }
- protected[headerNonce] = nonce
- }
-
- for k, v := range ctx.extraHeaders {
- protected[k] = v
- }
-
- serializedProtected := mustSerializeJSON(protected)
-
- input := []byte(fmt.Sprintf("%s.%s",
- base64.RawURLEncoding.EncodeToString(serializedProtected),
- base64.RawURLEncoding.EncodeToString(payload)))
-
- signatureInfo, err := recipient.signer.signPayload(input, recipient.sigAlg)
- if err != nil {
- return nil, err
- }
-
- signatureInfo.protected = &rawHeader{}
- for k, v := range protected {
- b, err := json.Marshal(v)
- if err != nil {
- return nil, fmt.Errorf("square/go-jose: Error marshalling item %#v: %v", k, err)
- }
- (*signatureInfo.protected)[k] = makeRawMessage(b)
- }
- obj.Signatures[i] = signatureInfo
- }
-
- return obj, nil
-}
-
-func (ctx *genericSigner) Options() SignerOptions {
- return SignerOptions{
- NonceSource: ctx.nonceSource,
- EmbedJWK: ctx.embedJWK,
- ExtraHeaders: ctx.extraHeaders,
- }
-}
-
-// Verify validates the signature on the object and returns the payload.
-// This function does not support multi-signature, if you desire multi-sig
-// verification use VerifyMulti instead.
-//
-// Be careful when verifying signatures based on embedded JWKs inside the
-// payload header. You cannot assume that the key received in a payload is
-// trusted.
-func (obj JSONWebSignature) Verify(verificationKey interface{}) ([]byte, error) {
- verifier, err := newVerifier(verificationKey)
- if err != nil {
- return nil, err
- }
-
- if len(obj.Signatures) > 1 {
- return nil, errors.New("square/go-jose: too many signatures in payload; expecting only one")
- }
-
- signature := obj.Signatures[0]
- headers := signature.mergedHeaders()
- critical, err := headers.getCritical()
- if err != nil {
- return nil, err
- }
- if len(critical) > 0 {
- // Unsupported crit header
- return nil, ErrCryptoFailure
- }
-
- input := obj.computeAuthData(&signature)
- alg := headers.getSignatureAlgorithm()
- err = verifier.verifyPayload(input, signature.Signature, alg)
- if err == nil {
- return obj.payload, nil
- }
-
- return nil, ErrCryptoFailure
-}
-
-// VerifyMulti validates (one of the multiple) signatures on the object and
-// returns the index of the signature that was verified, along with the signature
-// object and the payload. We return the signature and index to guarantee that
-// callers are getting the verified value.
-func (obj JSONWebSignature) VerifyMulti(verificationKey interface{}) (int, Signature, []byte, error) {
- verifier, err := newVerifier(verificationKey)
- if err != nil {
- return -1, Signature{}, nil, err
- }
-
- for i, signature := range obj.Signatures {
- headers := signature.mergedHeaders()
- critical, err := headers.getCritical()
- if err != nil {
- continue
- }
- if len(critical) > 0 {
- // Unsupported crit header
- continue
- }
-
- input := obj.computeAuthData(&signature)
- alg := headers.getSignatureAlgorithm()
- err = verifier.verifyPayload(input, signature.Signature, alg)
- if err == nil {
- return i, signature, obj.payload, nil
- }
- }
-
- return -1, Signature{}, nil, ErrCryptoFailure
-}