...

Source file src/gopkg.in/go-jose/go-jose.v2/opaque.go

Documentation: gopkg.in/go-jose/go-jose.v2

     1  /*-
     2   * Copyright 2018 Square Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package jose
    18  
    19  // OpaqueSigner is an interface that supports signing payloads with opaque
    20  // private key(s). Private key operations performed by implementers may, for
    21  // example, occur in a hardware module. An OpaqueSigner may rotate signing keys
    22  // transparently to the user of this interface.
    23  type OpaqueSigner interface {
    24  	// Public returns the public key of the current signing key.
    25  	Public() *JSONWebKey
    26  	// Algs returns a list of supported signing algorithms.
    27  	Algs() []SignatureAlgorithm
    28  	// SignPayload signs a payload with the current signing key using the given
    29  	// algorithm.
    30  	SignPayload(payload []byte, alg SignatureAlgorithm) ([]byte, error)
    31  }
    32  
    33  type opaqueSigner struct {
    34  	signer OpaqueSigner
    35  }
    36  
    37  func newOpaqueSigner(alg SignatureAlgorithm, signer OpaqueSigner) (recipientSigInfo, error) {
    38  	var algSupported bool
    39  	for _, salg := range signer.Algs() {
    40  		if alg == salg {
    41  			algSupported = true
    42  			break
    43  		}
    44  	}
    45  	if !algSupported {
    46  		return recipientSigInfo{}, ErrUnsupportedAlgorithm
    47  	}
    48  
    49  	return recipientSigInfo{
    50  		sigAlg:    alg,
    51  		publicKey: signer.Public,
    52  		signer: &opaqueSigner{
    53  			signer: signer,
    54  		},
    55  	}, nil
    56  }
    57  
    58  func (o *opaqueSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
    59  	out, err := o.signer.SignPayload(payload, alg)
    60  	if err != nil {
    61  		return Signature{}, err
    62  	}
    63  
    64  	return Signature{
    65  		Signature: out,
    66  		protected: &rawHeader{},
    67  	}, nil
    68  }
    69  
    70  // OpaqueVerifier is an interface that supports verifying payloads with opaque
    71  // public key(s). An OpaqueSigner may rotate signing keys transparently to the
    72  // user of this interface.
    73  type OpaqueVerifier interface {
    74  	VerifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error
    75  }
    76  
    77  type opaqueVerifier struct {
    78  	verifier OpaqueVerifier
    79  }
    80  
    81  func (o *opaqueVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
    82  	return o.verifier.VerifyPayload(payload, signature, alg)
    83  }
    84  
    85  // OpaqueKeyEncrypter is an interface that supports encrypting keys with an opaque key.
    86  type OpaqueKeyEncrypter interface {
    87  	// KeyID returns the kid
    88  	KeyID() string
    89  	// Algs returns a list of supported key encryption algorithms.
    90  	Algs() []KeyAlgorithm
    91  	// encryptKey encrypts the CEK using the given algorithm.
    92  	encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error)
    93  }
    94  
    95  type opaqueKeyEncrypter struct {
    96  	encrypter OpaqueKeyEncrypter
    97  }
    98  
    99  func newOpaqueKeyEncrypter(alg KeyAlgorithm, encrypter OpaqueKeyEncrypter) (recipientKeyInfo, error) {
   100  	var algSupported bool
   101  	for _, salg := range encrypter.Algs() {
   102  		if alg == salg {
   103  			algSupported = true
   104  			break
   105  		}
   106  	}
   107  	if !algSupported {
   108  		return recipientKeyInfo{}, ErrUnsupportedAlgorithm
   109  	}
   110  
   111  	return recipientKeyInfo{
   112  		keyID:  encrypter.KeyID(),
   113  		keyAlg: alg,
   114  		keyEncrypter: &opaqueKeyEncrypter{
   115  			encrypter: encrypter,
   116  		},
   117  	}, nil
   118  }
   119  
   120  func (oke *opaqueKeyEncrypter) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {
   121  	return oke.encrypter.encryptKey(cek, alg)
   122  }
   123  
   124  //OpaqueKeyDecrypter is an interface that supports decrypting keys with an opaque key.
   125  type OpaqueKeyDecrypter interface {
   126  	DecryptKey(encryptedKey []byte, header Header) ([]byte, error)
   127  }
   128  
   129  type opaqueKeyDecrypter struct {
   130  	decrypter OpaqueKeyDecrypter
   131  }
   132  
   133  func (okd *opaqueKeyDecrypter) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
   134  	mergedHeaders := rawHeader{}
   135  	mergedHeaders.merge(&headers)
   136  	mergedHeaders.merge(recipient.header)
   137  
   138  	header, err := mergedHeaders.sanitized()
   139  	if err != nil {
   140  		return nil, err
   141  	}
   142  
   143  	return okd.decrypter.DecryptKey(recipient.encryptedKey, header)
   144  }
   145  

View as plain text