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 17package jose 18 19// OpaqueSigner is an interface that supports signing payloads with opaque 20// private key(s). Private key operations preformed by implementors may, for 21// example, occur in a hardware module. An OpaqueSigner may rotate signing keys 22// transparently to the user of this interface. 23type 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 33type opaqueSigner struct { 34 signer OpaqueSigner 35} 36 37func 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 58func (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. 73type OpaqueVerifier interface { 74 VerifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error 75} 76 77type opaqueVerifier struct { 78 verifier OpaqueVerifier 79} 80 81func (o *opaqueVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error { 82 return o.verifier.VerifyPayload(payload, signature, alg) 83} 84