Merge v1.2.1-master
Signed-off-by: Emile Vauge <emile@vauge.com>
This commit is contained in:
parent
a590155b0b
commit
aeb17182b4
396 changed files with 27271 additions and 9969 deletions
24
vendor/gopkg.in/square/go-jose.v1/asymmetric.go
generated
vendored
24
vendor/gopkg.in/square/go-jose.v1/asymmetric.go
generated
vendored
|
@ -67,6 +67,10 @@ func newRSARecipient(keyAlg KeyAlgorithm, publicKey *rsa.PublicKey) (recipientKe
|
|||
return recipientKeyInfo{}, ErrUnsupportedAlgorithm
|
||||
}
|
||||
|
||||
if publicKey == nil {
|
||||
return recipientKeyInfo{}, errors.New("invalid public key")
|
||||
}
|
||||
|
||||
return recipientKeyInfo{
|
||||
keyAlg: keyAlg,
|
||||
keyEncrypter: &rsaEncrypterVerifier{
|
||||
|
@ -84,6 +88,10 @@ func newRSASigner(sigAlg SignatureAlgorithm, privateKey *rsa.PrivateKey) (recipi
|
|||
return recipientSigInfo{}, ErrUnsupportedAlgorithm
|
||||
}
|
||||
|
||||
if privateKey == nil {
|
||||
return recipientSigInfo{}, errors.New("invalid private key")
|
||||
}
|
||||
|
||||
return recipientSigInfo{
|
||||
sigAlg: sigAlg,
|
||||
publicKey: &JsonWebKey{
|
||||
|
@ -104,6 +112,10 @@ func newECDHRecipient(keyAlg KeyAlgorithm, publicKey *ecdsa.PublicKey) (recipien
|
|||
return recipientKeyInfo{}, ErrUnsupportedAlgorithm
|
||||
}
|
||||
|
||||
if publicKey == nil || !publicKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {
|
||||
return recipientKeyInfo{}, errors.New("invalid public key")
|
||||
}
|
||||
|
||||
return recipientKeyInfo{
|
||||
keyAlg: keyAlg,
|
||||
keyEncrypter: &ecEncrypterVerifier{
|
||||
|
@ -121,6 +133,10 @@ func newECDSASigner(sigAlg SignatureAlgorithm, privateKey *ecdsa.PrivateKey) (re
|
|||
return recipientSigInfo{}, ErrUnsupportedAlgorithm
|
||||
}
|
||||
|
||||
if privateKey == nil {
|
||||
return recipientSigInfo{}, errors.New("invalid private key")
|
||||
}
|
||||
|
||||
return recipientSigInfo{
|
||||
sigAlg: sigAlg,
|
||||
publicKey: &JsonWebKey{
|
||||
|
@ -199,7 +215,7 @@ func (ctx rsaDecrypterSigner) decrypt(jek []byte, alg KeyAlgorithm, generator ke
|
|||
// When decrypting an RSA-PKCS1v1.5 payload, we must take precautions to
|
||||
// prevent chosen-ciphertext attacks as described in RFC 3218, "Preventing
|
||||
// the Million Message Attack on Cryptographic Message Syntax". We are
|
||||
// therefore deliberatly ignoring errors here.
|
||||
// therefore deliberately ignoring errors here.
|
||||
_ = rsa.DecryptPKCS1v15SessionKey(rand.Reader, ctx.privateKey, jek, cek)
|
||||
|
||||
return cek, nil
|
||||
|
@ -370,6 +386,10 @@ func (ctx ecDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientI
|
|||
return nil, errors.New("square/go-jose: invalid epk header")
|
||||
}
|
||||
|
||||
if !ctx.privateKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {
|
||||
return nil, errors.New("square/go-jose: invalid public key in epk header")
|
||||
}
|
||||
|
||||
apuData := headers.Apu.bytes()
|
||||
apvData := headers.Apv.bytes()
|
||||
|
||||
|
@ -474,6 +494,8 @@ func (ctx ecEncrypterVerifier) verifyPayload(payload []byte, signature []byte, a
|
|||
case ES512:
|
||||
keySize = 66
|
||||
hash = crypto.SHA512
|
||||
default:
|
||||
return ErrUnsupportedAlgorithm
|
||||
}
|
||||
|
||||
if len(signature) != 2*keySize {
|
||||
|
|
16
vendor/gopkg.in/square/go-jose.v1/cipher/cbc_hmac.go
generated
vendored
16
vendor/gopkg.in/square/go-jose.v1/cipher/cbc_hmac.go
generated
vendored
|
@ -82,7 +82,7 @@ func (ctx *cbcAEAD) Overhead() int {
|
|||
// Seal encrypts and authenticates the plaintext.
|
||||
func (ctx *cbcAEAD) Seal(dst, nonce, plaintext, data []byte) []byte {
|
||||
// Output buffer -- must take care not to mangle plaintext input.
|
||||
ciphertext := make([]byte, len(plaintext)+ctx.Overhead())[:len(plaintext)]
|
||||
ciphertext := make([]byte, uint64(len(plaintext))+uint64(ctx.Overhead()))[:len(plaintext)]
|
||||
copy(ciphertext, plaintext)
|
||||
ciphertext = padBuffer(ciphertext, ctx.blockCipher.BlockSize())
|
||||
|
||||
|
@ -91,7 +91,7 @@ func (ctx *cbcAEAD) Seal(dst, nonce, plaintext, data []byte) []byte {
|
|||
cbc.CryptBlocks(ciphertext, ciphertext)
|
||||
authtag := ctx.computeAuthTag(data, nonce, ciphertext)
|
||||
|
||||
ret, out := resize(dst, len(dst)+len(ciphertext)+len(authtag))
|
||||
ret, out := resize(dst, uint64(len(dst))+uint64(len(ciphertext))+uint64(len(authtag)))
|
||||
copy(out, ciphertext)
|
||||
copy(out[len(ciphertext):], authtag)
|
||||
|
||||
|
@ -128,7 +128,7 @@ func (ctx *cbcAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
ret, out := resize(dst, len(dst)+len(plaintext))
|
||||
ret, out := resize(dst, uint64(len(dst))+uint64(len(plaintext)))
|
||||
copy(out, plaintext)
|
||||
|
||||
return ret, nil
|
||||
|
@ -136,12 +136,12 @@ func (ctx *cbcAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
|
|||
|
||||
// Compute an authentication tag
|
||||
func (ctx *cbcAEAD) computeAuthTag(aad, nonce, ciphertext []byte) []byte {
|
||||
buffer := make([]byte, len(aad)+len(nonce)+len(ciphertext)+8)
|
||||
buffer := make([]byte, uint64(len(aad))+uint64(len(nonce))+uint64(len(ciphertext))+8)
|
||||
n := 0
|
||||
n += copy(buffer, aad)
|
||||
n += copy(buffer[n:], nonce)
|
||||
n += copy(buffer[n:], ciphertext)
|
||||
binary.BigEndian.PutUint64(buffer[n:], uint64(len(aad)*8))
|
||||
binary.BigEndian.PutUint64(buffer[n:], uint64(len(aad))*8)
|
||||
|
||||
// According to documentation, Write() on hash.Hash never fails.
|
||||
hmac := hmac.New(ctx.hash, ctx.integrityKey)
|
||||
|
@ -153,8 +153,8 @@ func (ctx *cbcAEAD) computeAuthTag(aad, nonce, ciphertext []byte) []byte {
|
|||
// resize ensures the the given slice has a capacity of at least n bytes.
|
||||
// If the capacity of the slice is less than n, a new slice is allocated
|
||||
// and the existing data will be copied.
|
||||
func resize(in []byte, n int) (head, tail []byte) {
|
||||
if cap(in) >= n {
|
||||
func resize(in []byte, n uint64) (head, tail []byte) {
|
||||
if uint64(cap(in)) >= n {
|
||||
head = in[:n]
|
||||
} else {
|
||||
head = make([]byte, n)
|
||||
|
@ -168,7 +168,7 @@ func resize(in []byte, n int) (head, tail []byte) {
|
|||
// Apply padding
|
||||
func padBuffer(buffer []byte, blockSize int) []byte {
|
||||
missing := blockSize - (len(buffer) % blockSize)
|
||||
ret, out := resize(buffer, len(buffer)+missing)
|
||||
ret, out := resize(buffer, uint64(len(buffer))+uint64(missing))
|
||||
padding := bytes.Repeat([]byte{byte(missing)}, missing)
|
||||
copy(out, padding)
|
||||
return ret
|
||||
|
|
2
vendor/gopkg.in/square/go-jose.v1/cipher/concat_kdf.go
generated
vendored
2
vendor/gopkg.in/square/go-jose.v1/cipher/concat_kdf.go
generated
vendored
|
@ -32,7 +32,7 @@ type concatKDF struct {
|
|||
|
||||
// NewConcatKDF builds a KDF reader based on the given inputs.
|
||||
func NewConcatKDF(hash crypto.Hash, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo []byte) io.Reader {
|
||||
buffer := make([]byte, len(algID)+len(ptyUInfo)+len(ptyVInfo)+len(supPubInfo)+len(supPrivInfo))
|
||||
buffer := make([]byte, uint64(len(algID))+uint64(len(ptyUInfo))+uint64(len(ptyVInfo))+uint64(len(supPubInfo))+uint64(len(supPrivInfo)))
|
||||
n := 0
|
||||
n += copy(buffer, algID)
|
||||
n += copy(buffer[n:], ptyUInfo)
|
||||
|
|
11
vendor/gopkg.in/square/go-jose.v1/cipher/ecdh_es.go
generated
vendored
11
vendor/gopkg.in/square/go-jose.v1/cipher/ecdh_es.go
generated
vendored
|
@ -23,7 +23,14 @@ import (
|
|||
)
|
||||
|
||||
// DeriveECDHES derives a shared encryption key using ECDH/ConcatKDF as described in JWE/JWA.
|
||||
// It is an error to call this function with a private/public key that are not on the same
|
||||
// curve. Callers must ensure that the keys are valid before calling this function. Output
|
||||
// size may be at most 1<<16 bytes (64 KiB).
|
||||
func DeriveECDHES(alg string, apuData, apvData []byte, priv *ecdsa.PrivateKey, pub *ecdsa.PublicKey, size int) []byte {
|
||||
if size > 1<<16 {
|
||||
panic("ECDH-ES output size too large, must be less than 1<<16")
|
||||
}
|
||||
|
||||
// algId, partyUInfo, partyVInfo inputs must be prefixed with the length
|
||||
algID := lengthPrefixed([]byte(alg))
|
||||
ptyUInfo := lengthPrefixed(apuData)
|
||||
|
@ -33,6 +40,10 @@ func DeriveECDHES(alg string, apuData, apvData []byte, priv *ecdsa.PrivateKey, p
|
|||
supPubInfo := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(supPubInfo, uint32(size)*8)
|
||||
|
||||
if !priv.PublicKey.Curve.IsOnCurve(pub.X, pub.Y) {
|
||||
panic("public key not on same curve as private key")
|
||||
}
|
||||
|
||||
z, _ := priv.PublicKey.Curve.ScalarMult(pub.X, pub.Y, priv.D.Bytes())
|
||||
reader := NewConcatKDF(crypto.SHA256, z.Bytes(), algID, ptyUInfo, ptyVInfo, supPubInfo, []byte{})
|
||||
|
||||
|
|
79
vendor/gopkg.in/square/go-jose.v1/crypter.go
generated
vendored
79
vendor/gopkg.in/square/go-jose.v1/crypter.go
generated
vendored
|
@ -19,6 +19,7 @@ package jose
|
|||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
@ -292,10 +293,16 @@ func (ctx *genericEncrypter) EncryptWithAuthData(plaintext, aad []byte) (*JsonWe
|
|||
return obj, nil
|
||||
}
|
||||
|
||||
// Decrypt and validate the object and return the plaintext.
|
||||
// Decrypt and validate the object and return the plaintext. Note that this
|
||||
// function does not support multi-recipient, if you desire multi-recipient
|
||||
// decryption use DecryptMulti instead.
|
||||
func (obj JsonWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) {
|
||||
headers := obj.mergedHeaders(nil)
|
||||
|
||||
if len(obj.recipients) > 1 {
|
||||
return nil, errors.New("square/go-jose: too many recipients in payload; expecting only one")
|
||||
}
|
||||
|
||||
if len(headers.Crit) > 0 {
|
||||
return nil, fmt.Errorf("square/go-jose: unsupported crit header")
|
||||
}
|
||||
|
@ -323,7 +330,65 @@ func (obj JsonWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error)
|
|||
authData := obj.computeAuthData()
|
||||
|
||||
var plaintext []byte
|
||||
for _, recipient := range obj.recipients {
|
||||
recipient := obj.recipients[0]
|
||||
recipientHeaders := obj.mergedHeaders(&recipient)
|
||||
|
||||
cek, err := decrypter.decryptKey(recipientHeaders, &recipient, generator)
|
||||
if err == nil {
|
||||
// Found a valid CEK -- let's try to decrypt.
|
||||
plaintext, err = cipher.decrypt(cek, authData, parts)
|
||||
}
|
||||
|
||||
if plaintext == nil {
|
||||
return nil, ErrCryptoFailure
|
||||
}
|
||||
|
||||
// The "zip" header parameter may only be present in the protected header.
|
||||
if obj.protected.Zip != "" {
|
||||
plaintext, err = decompress(obj.protected.Zip, plaintext)
|
||||
}
|
||||
|
||||
return plaintext, err
|
||||
}
|
||||
|
||||
// DecryptMulti decrypts and validates the object and returns the plaintexts,
|
||||
// with support for multiple recipients. It returns the index of the recipient
|
||||
// for which the decryption was successful, the merged headers for that recipient,
|
||||
// and the plaintext.
|
||||
func (obj JsonWebEncryption) DecryptMulti(decryptionKey interface{}) (int, JoseHeader, []byte, error) {
|
||||
globalHeaders := obj.mergedHeaders(nil)
|
||||
|
||||
if len(globalHeaders.Crit) > 0 {
|
||||
return -1, JoseHeader{}, nil, fmt.Errorf("square/go-jose: unsupported crit header")
|
||||
}
|
||||
|
||||
decrypter, err := newDecrypter(decryptionKey)
|
||||
if err != nil {
|
||||
return -1, JoseHeader{}, nil, err
|
||||
}
|
||||
|
||||
cipher := getContentCipher(globalHeaders.Enc)
|
||||
if cipher == nil {
|
||||
return -1, JoseHeader{}, nil, fmt.Errorf("square/go-jose: unsupported enc value '%s'", string(globalHeaders.Enc))
|
||||
}
|
||||
|
||||
generator := randomKeyGenerator{
|
||||
size: cipher.keySize(),
|
||||
}
|
||||
|
||||
parts := &aeadParts{
|
||||
iv: obj.iv,
|
||||
ciphertext: obj.ciphertext,
|
||||
tag: obj.tag,
|
||||
}
|
||||
|
||||
authData := obj.computeAuthData()
|
||||
|
||||
index := -1
|
||||
var plaintext []byte
|
||||
var headers rawHeader
|
||||
|
||||
for i, recipient := range obj.recipients {
|
||||
recipientHeaders := obj.mergedHeaders(&recipient)
|
||||
|
||||
cek, err := decrypter.decryptKey(recipientHeaders, &recipient, generator)
|
||||
|
@ -331,19 +396,21 @@ func (obj JsonWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error)
|
|||
// Found a valid CEK -- let's try to decrypt.
|
||||
plaintext, err = cipher.decrypt(cek, authData, parts)
|
||||
if err == nil {
|
||||
index = i
|
||||
headers = recipientHeaders
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if plaintext == nil {
|
||||
return nil, ErrCryptoFailure
|
||||
if plaintext == nil || err != nil {
|
||||
return -1, JoseHeader{}, nil, ErrCryptoFailure
|
||||
}
|
||||
|
||||
// The "zip" header paramter may only be present in the protected header.
|
||||
// The "zip" header parameter may only be present in the protected header.
|
||||
if obj.protected.Zip != "" {
|
||||
plaintext, err = decompress(obj.protected.Zip, plaintext)
|
||||
}
|
||||
|
||||
return plaintext, err
|
||||
return index, headers.sanitized(), plaintext, err
|
||||
}
|
||||
|
|
8
vendor/gopkg.in/square/go-jose.v1/encoding.go
generated
vendored
8
vendor/gopkg.in/square/go-jose.v1/encoding.go
generated
vendored
|
@ -25,6 +25,8 @@ import (
|
|||
"math/big"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/square/go-jose.v1/json"
|
||||
)
|
||||
|
||||
var stripWhitespaceRegex = regexp.MustCompile("\\s")
|
||||
|
@ -45,7 +47,7 @@ func base64URLDecode(data string) ([]byte, error) {
|
|||
// Helper function to serialize known-good objects.
|
||||
// Precondition: value is not a nil pointer.
|
||||
func mustSerializeJSON(value interface{}) []byte {
|
||||
out, err := MarshalJSON(value)
|
||||
out, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -146,12 +148,12 @@ func newBufferFromInt(num uint64) *byteBuffer {
|
|||
}
|
||||
|
||||
func (b *byteBuffer) MarshalJSON() ([]byte, error) {
|
||||
return MarshalJSON(b.base64())
|
||||
return json.Marshal(b.base64())
|
||||
}
|
||||
|
||||
func (b *byteBuffer) UnmarshalJSON(data []byte) error {
|
||||
var encoded string
|
||||
err := UnmarshalJSON(data, &encoded)
|
||||
err := json.Unmarshal(data, &encoded)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
31
vendor/gopkg.in/square/go-jose.v1/json_fork.go
generated
vendored
31
vendor/gopkg.in/square/go-jose.v1/json_fork.go
generated
vendored
|
@ -1,31 +0,0 @@
|
|||
// +build !std_json
|
||||
|
||||
/*-
|
||||
* 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 (
|
||||
"gopkg.in/square/go-jose.v1/json"
|
||||
)
|
||||
|
||||
func MarshalJSON(v interface{}) ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
func UnmarshalJSON(data []byte, v interface{}) error {
|
||||
return json.Unmarshal(data, v)
|
||||
}
|
31
vendor/gopkg.in/square/go-jose.v1/json_std.go
generated
vendored
31
vendor/gopkg.in/square/go-jose.v1/json_std.go
generated
vendored
|
@ -1,31 +0,0 @@
|
|||
// +build std_json
|
||||
|
||||
/*-
|
||||
* 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 (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
func MarshalJSON(v interface{}) ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
func UnmarshalJSON(data []byte, v interface{}) error {
|
||||
return json.Unmarshal(data, v)
|
||||
}
|
6
vendor/gopkg.in/square/go-jose.v1/jwe.go
generated
vendored
6
vendor/gopkg.in/square/go-jose.v1/jwe.go
generated
vendored
|
@ -19,6 +19,8 @@ package jose
|
|||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/square/go-jose.v1/json"
|
||||
)
|
||||
|
||||
// rawJsonWebEncryption represents a raw JWE JSON object. Used for parsing/serializing.
|
||||
|
@ -111,7 +113,7 @@ func ParseEncrypted(input string) (*JsonWebEncryption, error) {
|
|||
// parseEncryptedFull parses a message in compact format.
|
||||
func parseEncryptedFull(input string) (*JsonWebEncryption, error) {
|
||||
var parsed rawJsonWebEncryption
|
||||
err := UnmarshalJSON([]byte(input), &parsed)
|
||||
err := json.Unmarshal([]byte(input), &parsed)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -133,7 +135,7 @@ func (parsed *rawJsonWebEncryption) sanitized() (*JsonWebEncryption, error) {
|
|||
}
|
||||
|
||||
if parsed.Protected != nil && len(parsed.Protected.bytes()) > 0 {
|
||||
err := UnmarshalJSON(parsed.Protected.bytes(), &obj.protected)
|
||||
err := json.Unmarshal(parsed.Protected.bytes(), &obj.protected)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("square/go-jose: invalid protected header: %s, %s", err, parsed.Protected.base64())
|
||||
}
|
||||
|
|
73
vendor/gopkg.in/square/go-jose.v1/jwk.go
generated
vendored
73
vendor/gopkg.in/square/go-jose.v1/jwk.go
generated
vendored
|
@ -21,10 +21,15 @@ import (
|
|||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/square/go-jose.v1/json"
|
||||
)
|
||||
|
||||
// rawJsonWebKey represents a public or private key in JWK format, used for parsing/serializing.
|
||||
|
@ -49,14 +54,17 @@ type rawJsonWebKey struct {
|
|||
Dp *byteBuffer `json:"dp,omitempty"`
|
||||
Dq *byteBuffer `json:"dq,omitempty"`
|
||||
Qi *byteBuffer `json:"qi,omitempty"`
|
||||
// Certificates
|
||||
X5c []string `json:"x5c,omitempty"`
|
||||
}
|
||||
|
||||
// JsonWebKey represents a public or private key in JWK format.
|
||||
type JsonWebKey struct {
|
||||
Key interface{}
|
||||
KeyID string
|
||||
Algorithm string
|
||||
Use string
|
||||
Key interface{}
|
||||
Certificates []*x509.Certificate
|
||||
KeyID string
|
||||
Algorithm string
|
||||
Use string
|
||||
}
|
||||
|
||||
// MarshalJSON serializes the given key to its JSON representation.
|
||||
|
@ -87,13 +95,17 @@ func (k JsonWebKey) MarshalJSON() ([]byte, error) {
|
|||
raw.Alg = k.Algorithm
|
||||
raw.Use = k.Use
|
||||
|
||||
return MarshalJSON(raw)
|
||||
for _, cert := range k.Certificates {
|
||||
raw.X5c = append(raw.X5c, base64.StdEncoding.EncodeToString(cert.Raw))
|
||||
}
|
||||
|
||||
return json.Marshal(raw)
|
||||
}
|
||||
|
||||
// UnmarshalJSON reads a key from its JSON representation.
|
||||
func (k *JsonWebKey) UnmarshalJSON(data []byte) (err error) {
|
||||
var raw rawJsonWebKey
|
||||
err = UnmarshalJSON(data, &raw)
|
||||
err = json.Unmarshal(data, &raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -121,6 +133,19 @@ func (k *JsonWebKey) UnmarshalJSON(data []byte) (err error) {
|
|||
if err == nil {
|
||||
*k = JsonWebKey{Key: key, KeyID: raw.Kid, Algorithm: raw.Alg, Use: raw.Use}
|
||||
}
|
||||
|
||||
k.Certificates = make([]*x509.Certificate, len(raw.X5c))
|
||||
for i, cert := range raw.X5c {
|
||||
raw, err := base64.StdEncoding.DecodeString(cert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
k.Certificates[i], err = x509.ParseCertificate(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -192,7 +217,17 @@ func (k *JsonWebKey) Thumbprint(hash crypto.Hash) ([]byte, error) {
|
|||
return h.Sum(nil), nil
|
||||
}
|
||||
|
||||
// Valid checks that the key contains the expected parameters
|
||||
// IsPublic returns true if the JWK represents a public key (not symmetric, not private).
|
||||
func (k *JsonWebKey) IsPublic() bool {
|
||||
switch k.Key.(type) {
|
||||
case *ecdsa.PublicKey, *rsa.PublicKey:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Valid checks that the key contains the expected parameters.
|
||||
func (k *JsonWebKey) Valid() bool {
|
||||
if k.Key == nil {
|
||||
return false
|
||||
|
@ -253,13 +288,20 @@ func (key rawJsonWebKey) ecPublicKey() (*ecdsa.PublicKey, error) {
|
|||
}
|
||||
|
||||
if key.X == nil || key.Y == nil {
|
||||
return nil, fmt.Errorf("square/go-jose: invalid EC key, missing x/y values")
|
||||
return nil, errors.New("square/go-jose: invalid EC key, missing x/y values")
|
||||
}
|
||||
|
||||
x := key.X.bigInt()
|
||||
y := key.Y.bigInt()
|
||||
|
||||
if !curve.IsOnCurve(x, y) {
|
||||
return nil, errors.New("square/go-jose: invalid EC key, X/Y are not on declared curve")
|
||||
}
|
||||
|
||||
return &ecdsa.PublicKey{
|
||||
Curve: curve,
|
||||
X: key.X.bigInt(),
|
||||
Y: key.Y.bigInt(),
|
||||
X: x,
|
||||
Y: y,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -368,11 +410,18 @@ func (key rawJsonWebKey) ecPrivateKey() (*ecdsa.PrivateKey, error) {
|
|||
return nil, fmt.Errorf("square/go-jose: invalid EC private key, missing x/y/d values")
|
||||
}
|
||||
|
||||
x := key.X.bigInt()
|
||||
y := key.Y.bigInt()
|
||||
|
||||
if !curve.IsOnCurve(x, y) {
|
||||
return nil, errors.New("square/go-jose: invalid EC key, X/Y are not on declared curve")
|
||||
}
|
||||
|
||||
return &ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: curve,
|
||||
X: key.X.bigInt(),
|
||||
Y: key.Y.bigInt(),
|
||||
X: x,
|
||||
Y: y,
|
||||
},
|
||||
D: key.D.bigInt(),
|
||||
}, nil
|
||||
|
|
32
vendor/gopkg.in/square/go-jose.v1/jws.go
generated
vendored
32
vendor/gopkg.in/square/go-jose.v1/jws.go
generated
vendored
|
@ -17,8 +17,11 @@
|
|||
package jose
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/square/go-jose.v1/json"
|
||||
)
|
||||
|
||||
// rawJsonWebSignature represents a raw JWS JSON object. Used for parsing/serializing.
|
||||
|
@ -39,7 +42,10 @@ type rawSignatureInfo struct {
|
|||
|
||||
// JsonWebSignature represents a signed JWS object after parsing.
|
||||
type JsonWebSignature struct {
|
||||
payload []byte
|
||||
payload []byte
|
||||
// Signatures attached to this object (may be more than one for multi-sig).
|
||||
// Be careful about accessing these directly, prefer to use Verify() or
|
||||
// VerifyMulti() to ensure that the data you're getting is verified.
|
||||
Signatures []Signature
|
||||
}
|
||||
|
||||
|
@ -56,7 +62,7 @@ type Signature struct {
|
|||
original *rawSignatureInfo
|
||||
}
|
||||
|
||||
// ParseSigned parses an encrypted message in compact or full serialization format.
|
||||
// ParseSigned parses a signed message in compact or full serialization format.
|
||||
func ParseSigned(input string) (*JsonWebSignature, error) {
|
||||
input = stripWhitespace(input)
|
||||
if strings.HasPrefix(input, "{") {
|
||||
|
@ -94,7 +100,7 @@ func (obj JsonWebSignature) computeAuthData(signature *Signature) []byte {
|
|||
// parseSignedFull parses a message in full format.
|
||||
func parseSignedFull(input string) (*JsonWebSignature, error) {
|
||||
var parsed rawJsonWebSignature
|
||||
err := UnmarshalJSON([]byte(input), &parsed)
|
||||
err := json.Unmarshal([]byte(input), &parsed)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -118,12 +124,13 @@ func (parsed *rawJsonWebSignature) sanitized() (*JsonWebSignature, error) {
|
|||
signature := Signature{}
|
||||
if parsed.Protected != nil && len(parsed.Protected.bytes()) > 0 {
|
||||
signature.protected = &rawHeader{}
|
||||
err := UnmarshalJSON(parsed.Protected.bytes(), signature.protected)
|
||||
err := json.Unmarshal(parsed.Protected.bytes(), signature.protected)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Check that there is not a nonce in the unprotected header
|
||||
if parsed.Header != nil && parsed.Header.Nonce != "" {
|
||||
return nil, ErrUnprotectedNonce
|
||||
}
|
||||
|
@ -146,13 +153,20 @@ func (parsed *rawJsonWebSignature) sanitized() (*JsonWebSignature, error) {
|
|||
}
|
||||
|
||||
signature.Header = signature.mergedHeaders().sanitized()
|
||||
|
||||
// As per RFC 7515 Section 4.1.3, only public keys are allowed to be embedded.
|
||||
jwk := signature.Header.JsonWebKey
|
||||
if jwk != nil && (!jwk.Valid() || !jwk.IsPublic()) {
|
||||
return nil, errors.New("square/go-jose: invalid embedded jwk, must be public key")
|
||||
}
|
||||
|
||||
obj.Signatures = append(obj.Signatures, signature)
|
||||
}
|
||||
|
||||
for i, sig := range parsed.Signatures {
|
||||
if sig.Protected != nil && len(sig.Protected.bytes()) > 0 {
|
||||
obj.Signatures[i].protected = &rawHeader{}
|
||||
err := UnmarshalJSON(sig.Protected.bytes(), obj.Signatures[i].protected)
|
||||
err := json.Unmarshal(sig.Protected.bytes(), obj.Signatures[i].protected)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -163,14 +177,20 @@ func (parsed *rawJsonWebSignature) sanitized() (*JsonWebSignature, error) {
|
|||
return nil, ErrUnprotectedNonce
|
||||
}
|
||||
|
||||
obj.Signatures[i].Header = obj.Signatures[i].mergedHeaders().sanitized()
|
||||
obj.Signatures[i].Signature = sig.Signature.bytes()
|
||||
|
||||
// As per RFC 7515 Section 4.1.3, only public keys are allowed to be embedded.
|
||||
jwk := obj.Signatures[i].Header.JsonWebKey
|
||||
if jwk != nil && (!jwk.Valid() || !jwk.IsPublic()) {
|
||||
return nil, errors.New("square/go-jose: invalid embedded jwk, must be public key")
|
||||
}
|
||||
|
||||
// Copy value of sig
|
||||
original := sig
|
||||
|
||||
obj.Signatures[i].header = sig.Header
|
||||
obj.Signatures[i].original = &original
|
||||
obj.Signatures[i].Header = obj.Signatures[i].mergedHeaders().sanitized()
|
||||
}
|
||||
|
||||
return obj, nil
|
||||
|
|
50
vendor/gopkg.in/square/go-jose.v1/signing.go
generated
vendored
50
vendor/gopkg.in/square/go-jose.v1/signing.go
generated
vendored
|
@ -19,6 +19,7 @@ package jose
|
|||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
|
@ -186,20 +187,59 @@ func (ctx *genericSigner) SetNonceSource(source NonceSource) {
|
|||
ctx.nonceSource = source
|
||||
}
|
||||
|
||||
// SetEmbedJwk specifies if the signing key should be embedded in the protected header,
|
||||
// if any. It defaults to 'true'.
|
||||
// SetEmbedJwk specifies if the signing key should be embedded in the protected
|
||||
// header, if any. It defaults to 'true', though that may change in the future.
|
||||
// Note that the use of embedded JWKs in the signature header can be dangerous,
|
||||
// as you cannot assume that the key received in a payload is trusted.
|
||||
func (ctx *genericSigner) SetEmbedJwk(embed bool) {
|
||||
ctx.embedJwk = embed
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
for _, signature := range obj.Signatures {
|
||||
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()
|
||||
if len(headers.Crit) > 0 {
|
||||
// Unsupported crit header
|
||||
return nil, ErrCryptoFailure
|
||||
}
|
||||
|
||||
input := obj.computeAuthData(&signature)
|
||||
alg := SignatureAlgorithm(headers.Alg)
|
||||
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()
|
||||
if len(headers.Crit) > 0 {
|
||||
// Unsupported crit header
|
||||
|
@ -210,9 +250,9 @@ func (obj JsonWebSignature) Verify(verificationKey interface{}) ([]byte, error)
|
|||
alg := SignatureAlgorithm(headers.Alg)
|
||||
err := verifier.verifyPayload(input, signature.Signature, alg)
|
||||
if err == nil {
|
||||
return obj.payload, nil
|
||||
return i, signature, obj.payload, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, ErrCryptoFailure
|
||||
return -1, Signature{}, nil, ErrCryptoFailure
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue