vendor: revendor
This commit is contained in:
1
vendor/gopkg.in/square/go-jose.v2/.gitcookies.sh.enc
generated
vendored
1
vendor/gopkg.in/square/go-jose.v2/.gitcookies.sh.enc
generated
vendored
@@ -1 +0,0 @@
|
||||
'|<7C>&{t<>U|gG<67>(<1E><>Cy=+<13><><EFBFBD>c<EFBFBD>:u:/p<>#~<7E><>["<22>4<EFBFBD>!<21>n<EFBFBD>A<EFBFBD>DK<<3C>uf<75>h<>a<EFBFBD><14>:<3A><><EFBFBD><EFBFBD><EFBFBD>B/<2F>ؤ<EFBFBD><D8A4><08>_<EFBFBD>h<EFBFBD><68>S<17>T*w<>x<EFBFBD><78><12><>-<2D>|<7C><><EFBFBD>Ӄ<EFBFBD><D383><EFBFBD><EFBFBD><14>㣗A$$<24>6<EFBFBD><36><03>G)8n<38>p<EFBFBD><12>ˡ3̚<33>o<><6F>v<>B<>3<EFBFBD><33>]xݓ<78>2l<>G<EFBFBD>|qRޯ
|
7
vendor/gopkg.in/square/go-jose.v2/.gitignore
generated
vendored
7
vendor/gopkg.in/square/go-jose.v2/.gitignore
generated
vendored
@@ -1,7 +0,0 @@
|
||||
*~
|
||||
.*.swp
|
||||
*.out
|
||||
*.test
|
||||
*.pem
|
||||
*.cov
|
||||
jose-util/jose-util
|
45
vendor/gopkg.in/square/go-jose.v2/.travis.yml
generated
vendored
45
vendor/gopkg.in/square/go-jose.v2/.travis.yml
generated
vendored
@@ -1,45 +0,0 @@
|
||||
language: go
|
||||
|
||||
sudo: false
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- go: tip
|
||||
|
||||
go:
|
||||
- 1.5
|
||||
- 1.6
|
||||
- 1.7
|
||||
- tip
|
||||
|
||||
go_import_path: gopkg.in/square/go-jose.v2
|
||||
|
||||
before_script:
|
||||
- export PATH=$HOME/.local/bin:$PATH
|
||||
|
||||
before_install:
|
||||
# Install encrypted gitcookies to get around bandwidth-limits
|
||||
# that is causing Travis-CI builds to fail. For more info, see
|
||||
# https://github.com/golang/go/issues/12933
|
||||
- openssl aes-256-cbc -K $encrypted_1528c3c2cafd_key -iv $encrypted_1528c3c2cafd_iv -in .gitcookies.sh.enc -out .gitcookies.sh -d || true
|
||||
- bash .gitcookies.sh || true
|
||||
- go get github.com/wadey/gocovmerge
|
||||
- go get github.com/mattn/goveralls
|
||||
- go get github.com/stretchr/testify/assert
|
||||
- go get golang.org/x/tools/cmd/cover || true
|
||||
- go get code.google.com/p/go.tools/cmd/cover || true
|
||||
- pip install cram --user `whoami`
|
||||
|
||||
script:
|
||||
- go test . -v -covermode=count -coverprofile=profile.cov
|
||||
- go test ./cipher -v -covermode=count -coverprofile=cipher/profile.cov
|
||||
- go test ./jwt -v -covermode=count -coverprofile=jwt/profile.cov
|
||||
- go test ./json -v # no coverage for forked encoding/json package
|
||||
- cd jose-util && go build && PATH=$PWD:$PATH cram -v jose-util.t
|
||||
- cd ..
|
||||
|
||||
after_success:
|
||||
- gocovmerge *.cov */*.cov > merged.coverprofile
|
||||
- $HOME/gopath/bin/goveralls -coverprofile merged.coverprofile -service=travis-ci
|
||||
|
10
vendor/gopkg.in/square/go-jose.v2/BUG-BOUNTY.md
generated
vendored
10
vendor/gopkg.in/square/go-jose.v2/BUG-BOUNTY.md
generated
vendored
@@ -1,10 +0,0 @@
|
||||
Serious about security
|
||||
======================
|
||||
|
||||
Square recognizes the important contributions the security research community
|
||||
can make. We therefore encourage reporting security issues with the code
|
||||
contained in this repository.
|
||||
|
||||
If you believe you have discovered a security vulnerability, please follow the
|
||||
guidelines at <https://hackerone.com/square-open-source>.
|
||||
|
14
vendor/gopkg.in/square/go-jose.v2/CONTRIBUTING.md
generated
vendored
14
vendor/gopkg.in/square/go-jose.v2/CONTRIBUTING.md
generated
vendored
@@ -1,14 +0,0 @@
|
||||
# Contributing
|
||||
|
||||
If you would like to contribute code to go-jose you can do so through GitHub by
|
||||
forking the repository and sending a pull request.
|
||||
|
||||
When submitting code, please make every effort to follow existing conventions
|
||||
and style in order to keep the code as readable as possible. Please also make
|
||||
sure all tests pass by running `go test`, and format your code with `go fmt`.
|
||||
We also recommend using `golint` and `errcheck`.
|
||||
|
||||
Before your code can be accepted into the project you must also sign the
|
||||
[Individual Contributor License Agreement][1].
|
||||
|
||||
[1]: https://spreadsheets.google.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1
|
119
vendor/gopkg.in/square/go-jose.v2/README.md
generated
vendored
119
vendor/gopkg.in/square/go-jose.v2/README.md
generated
vendored
@@ -1,119 +0,0 @@
|
||||
# Go JOSE
|
||||
|
||||
[](https://godoc.org/gopkg.in/square/go-jose.v1)
|
||||
[](https://godoc.org/gopkg.in/square/go-jose.v2)
|
||||
[](https://raw.githubusercontent.com/square/go-jose/master/LICENSE)
|
||||
[](https://travis-ci.org/square/go-jose)
|
||||
[](https://coveralls.io/r/square/go-jose)
|
||||
|
||||
Package jose aims to provide an implementation of the Javascript Object Signing
|
||||
and Encryption set of standards. This includes support for JSON Web Encryption,
|
||||
JSON Web Signature, and JSON Web Token standards.
|
||||
|
||||
**Disclaimer**: This library contains encryption software that is subject to
|
||||
the U.S. Export Administration Regulations. You may not export, re-export,
|
||||
transfer or download this code or any part of it in violation of any United
|
||||
States law, directive or regulation. In particular this software may not be
|
||||
exported or re-exported in any form or on any media to Iran, North Sudan,
|
||||
Syria, Cuba, or North Korea, or to denied persons or entities mentioned on any
|
||||
US maintained blocked list.
|
||||
|
||||
## Overview
|
||||
|
||||
The implementation follows the
|
||||
[JSON Web Encryption](http://dx.doi.org/10.17487/RFC7516) (RFC 7516),
|
||||
[JSON Web Signature](http://dx.doi.org/10.17487/RFC7515) (RFC 7515), and
|
||||
[JSON Web Token](http://dx.doi.org/10.17487/RFC7519) (RFC 7519).
|
||||
Tables of supported algorithms are shown below. The library supports both
|
||||
the compact and full serialization formats, and has optional support for
|
||||
multiple recipients. It also comes with a small command-line utility
|
||||
([`jose-util`](https://github.com/square/go-jose/tree/v2/jose-util))
|
||||
for dealing with JOSE messages in a shell.
|
||||
|
||||
**Note**: We use a forked version of the `encoding/json` package from the Go
|
||||
standard library which uses case-sensitive matching for member names (instead
|
||||
of [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html)).
|
||||
This is to avoid differences in interpretation of messages between go-jose and
|
||||
libraries in other languages.
|
||||
|
||||
### Versions
|
||||
|
||||
We use [gopkg.in](https://gopkg.in) for versioning.
|
||||
|
||||
[Version 1](https://gopkg.in/square/go-jose.v1) is the old stable version:
|
||||
|
||||
import "gopkg.in/square/go-jose.v1"
|
||||
|
||||
[Version 2](https://gopkg.in/square/go-jose.v2) is for new development:
|
||||
|
||||
import "gopkg.in/square/go-jose.v2"
|
||||
|
||||
The interface for [go-jose.v1](https://gopkg.in/square/go-jose.v1) will remain
|
||||
backwards compatible. No new feature development will take place on the `v1` branch,
|
||||
however bug fixes and security fixes will be backported.
|
||||
|
||||
The interface for [go-jose.v2](https://gopkg.in/square/go-jose.v2) is mostly
|
||||
stable, but we suggest pinning to a particular revision for now as we still reserve
|
||||
the right to make changes. New feature development happens on this branch.
|
||||
|
||||
New in [go-jose.v2](https://gopkg.in/square/go-jose.v2) is a
|
||||
[jwt](https://godoc.org/gopkg.in/square/go-jose.v2/jwt) sub-package
|
||||
contributed by [@shaxbee](https://github.com/shaxbee).
|
||||
|
||||
### Supported algorithms
|
||||
|
||||
See below for a table of supported algorithms. Algorithm identifiers match
|
||||
the names in the [JSON Web Algorithms](http://dx.doi.org/10.17487/RFC7518)
|
||||
standard where possible. The Godoc reference has a list of constants.
|
||||
|
||||
Key encryption | Algorithm identifier(s)
|
||||
:------------------------- | :------------------------------
|
||||
RSA-PKCS#1v1.5 | RSA1_5
|
||||
RSA-OAEP | RSA-OAEP, RSA-OAEP-256
|
||||
AES key wrap | A128KW, A192KW, A256KW
|
||||
AES-GCM key wrap | A128GCMKW, A192GCMKW, A256GCMKW
|
||||
ECDH-ES + AES key wrap | ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW
|
||||
ECDH-ES (direct) | ECDH-ES<sup>1</sup>
|
||||
Direct encryption | dir<sup>1</sup>
|
||||
|
||||
<sup>1. Not supported in multi-recipient mode</sup>
|
||||
|
||||
Signing / MAC | Algorithm identifier(s)
|
||||
:------------------------- | :------------------------------
|
||||
RSASSA-PKCS#1v1.5 | RS256, RS384, RS512
|
||||
RSASSA-PSS | PS256, PS384, PS512
|
||||
HMAC | HS256, HS384, HS512
|
||||
ECDSA | ES256, ES384, ES512
|
||||
|
||||
Content encryption | Algorithm identifier(s)
|
||||
:------------------------- | :------------------------------
|
||||
AES-CBC+HMAC | A128CBC-HS256, A192CBC-HS384, A256CBC-HS512
|
||||
AES-GCM | A128GCM, A192GCM, A256GCM
|
||||
|
||||
Compression | Algorithm identifiers(s)
|
||||
:------------------------- | -------------------------------
|
||||
DEFLATE (RFC 1951) | DEF
|
||||
|
||||
### Supported key types
|
||||
|
||||
See below for a table of supported key types. These are understood by the
|
||||
library, and can be passed to corresponding functions such as `NewEncrypter` or
|
||||
`NewSigner`. Each of these keys can also be wrapped in a JWK if desired, which
|
||||
allows attaching a key id.
|
||||
|
||||
Algorithm(s) | Corresponding types
|
||||
:------------------------- | -------------------------------
|
||||
RSA | *[rsa.PublicKey](http://golang.org/pkg/crypto/rsa/#PublicKey), *[rsa.PrivateKey](http://golang.org/pkg/crypto/rsa/#PrivateKey)
|
||||
ECDH, ECDSA | *[ecdsa.PublicKey](http://golang.org/pkg/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](http://golang.org/pkg/crypto/ecdsa/#PrivateKey)
|
||||
AES, HMAC | []byte
|
||||
|
||||
## Examples
|
||||
|
||||
[](https://godoc.org/gopkg.in/square/go-jose.v1)
|
||||
[](https://godoc.org/gopkg.in/square/go-jose.v2)
|
||||
|
||||
Examples can be found in the Godoc
|
||||
reference for this package. The
|
||||
[`jose-util`](https://github.com/square/go-jose/tree/v2/jose-util)
|
||||
subdirectory also contains a small command-line utility which might be useful
|
||||
as an example.
|
468
vendor/gopkg.in/square/go-jose.v2/asymmetric_test.go
generated
vendored
468
vendor/gopkg.in/square/go-jose.v2/asymmetric_test.go
generated
vendored
@@ -1,468 +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 (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"errors"
|
||||
"io"
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestVectorsRSA(t *testing.T) {
|
||||
// Sources:
|
||||
// http://www.emc.com/emc-plus/rsa-labs/standards-initiatives/pkcs-rsa-cryptography-standard.htm
|
||||
// ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15crypt-vectors.txt
|
||||
priv := &rsa.PrivateKey{
|
||||
PublicKey: rsa.PublicKey{
|
||||
N: fromHexInt(`
|
||||
a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8
|
||||
ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0c
|
||||
bc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bd
|
||||
bf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93
|
||||
ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb`),
|
||||
E: 65537,
|
||||
},
|
||||
D: fromHexInt(`
|
||||
53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf1195
|
||||
17ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d
|
||||
4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d6
|
||||
5a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb
|
||||
04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1`),
|
||||
Primes: []*big.Int{
|
||||
fromHexInt(`
|
||||
d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262
|
||||
864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c
|
||||
2f26a471dcad212eac7ca39d`),
|
||||
fromHexInt(`
|
||||
cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb3
|
||||
3d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af
|
||||
72bfe9a030e860b0288b5d77`),
|
||||
},
|
||||
}
|
||||
|
||||
input := fromHexBytes(
|
||||
"6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34")
|
||||
|
||||
expectedPKCS := fromHexBytes(`
|
||||
50b4c14136bd198c2f3c3ed243fce036e168d56517984a263cd66492b808
|
||||
04f169d210f2b9bdfb48b12f9ea05009c77da257cc600ccefe3a6283789d
|
||||
8ea0e607ac58e2690ec4ebc10146e8cbaa5ed4d5cce6fe7b0ff9efc1eabb
|
||||
564dbf498285f449ee61dd7b42ee5b5892cb90601f30cda07bf26489310b
|
||||
cd23b528ceab3c31`)
|
||||
|
||||
expectedOAEP := fromHexBytes(`
|
||||
354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad4
|
||||
68fb21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618
|
||||
c21a535fa9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e6
|
||||
57a05a266426d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5
|
||||
210035d47ac72e8a`)
|
||||
|
||||
// Mock random reader
|
||||
randReader = bytes.NewReader(fromHexBytes(`
|
||||
017341ae3875d5f87101f8cc4fa9b9bc156bb04628fccdb2f4f11e905bd3
|
||||
a155d376f593bd7304210874eba08a5e22bcccb4c9d3882a93a54db022f5
|
||||
03d16338b6b7ce16dc7f4bbf9a96b59772d6606e9747c7649bf9e083db98
|
||||
1884a954ab3c6f18b776ea21069d69776a33e96bad48e1dda0a5ef`))
|
||||
defer resetRandReader()
|
||||
|
||||
// RSA-PKCS1v1.5 encrypt
|
||||
enc := new(rsaEncrypterVerifier)
|
||||
enc.publicKey = &priv.PublicKey
|
||||
encryptedPKCS, err := enc.encrypt(input, RSA1_5)
|
||||
if err != nil {
|
||||
t.Error("Encryption failed:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if bytes.Compare(encryptedPKCS, expectedPKCS) != 0 {
|
||||
t.Error("Output does not match expected value (PKCS1v1.5)")
|
||||
}
|
||||
|
||||
// RSA-OAEP encrypt
|
||||
encryptedOAEP, err := enc.encrypt(input, RSA_OAEP)
|
||||
if err != nil {
|
||||
t.Error("Encryption failed:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if bytes.Compare(encryptedOAEP, expectedOAEP) != 0 {
|
||||
t.Error("Output does not match expected value (OAEP)")
|
||||
}
|
||||
|
||||
// Need fake cipher for PKCS1v1.5 decrypt
|
||||
resetRandReader()
|
||||
aes := newAESGCM(len(input))
|
||||
|
||||
keygen := randomKeyGenerator{
|
||||
size: aes.keySize(),
|
||||
}
|
||||
|
||||
// RSA-PKCS1v1.5 decrypt
|
||||
dec := new(rsaDecrypterSigner)
|
||||
dec.privateKey = priv
|
||||
decryptedPKCS, err := dec.decrypt(encryptedPKCS, RSA1_5, keygen)
|
||||
if err != nil {
|
||||
t.Error("Decryption failed:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if bytes.Compare(input, decryptedPKCS) != 0 {
|
||||
t.Error("Output does not match expected value (PKCS1v1.5)")
|
||||
}
|
||||
|
||||
// RSA-OAEP decrypt
|
||||
decryptedOAEP, err := dec.decrypt(encryptedOAEP, RSA_OAEP, keygen)
|
||||
if err != nil {
|
||||
t.Error("decryption failed:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if bytes.Compare(input, decryptedOAEP) != 0 {
|
||||
t.Error("output does not match expected value (OAEP)")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidAlgorithmsRSA(t *testing.T) {
|
||||
_, err := newRSARecipient("XYZ", nil)
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
|
||||
_, err = newRSASigner("XYZ", nil)
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
|
||||
enc := new(rsaEncrypterVerifier)
|
||||
enc.publicKey = &rsaTestKey.PublicKey
|
||||
_, err = enc.encryptKey([]byte{}, "XYZ")
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
|
||||
err = enc.verifyPayload([]byte{}, []byte{}, "XYZ")
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
|
||||
dec := new(rsaDecrypterSigner)
|
||||
dec.privateKey = rsaTestKey
|
||||
_, err = dec.decrypt(make([]byte, 256), "XYZ", randomKeyGenerator{size: 16})
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
|
||||
_, err = dec.signPayload([]byte{}, "XYZ")
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
}
|
||||
|
||||
type failingKeyGenerator struct{}
|
||||
|
||||
func (ctx failingKeyGenerator) keySize() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (ctx failingKeyGenerator) genKey() ([]byte, rawHeader, error) {
|
||||
return nil, rawHeader{}, errors.New("failed to generate key")
|
||||
}
|
||||
|
||||
func TestPKCSKeyGeneratorFailure(t *testing.T) {
|
||||
dec := new(rsaDecrypterSigner)
|
||||
dec.privateKey = rsaTestKey
|
||||
generator := failingKeyGenerator{}
|
||||
_, err := dec.decrypt(make([]byte, 256), RSA1_5, generator)
|
||||
if err != ErrCryptoFailure {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidAlgorithmsEC(t *testing.T) {
|
||||
_, err := newECDHRecipient("XYZ", nil)
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
|
||||
_, err = newECDSASigner("XYZ", nil)
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
|
||||
enc := new(ecEncrypterVerifier)
|
||||
enc.publicKey = &ecTestKey256.PublicKey
|
||||
_, err = enc.encryptKey([]byte{}, "XYZ")
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should return error on invalid algorithm")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidECKeyGen(t *testing.T) {
|
||||
gen := ecKeyGenerator{
|
||||
size: 16,
|
||||
algID: "A128GCM",
|
||||
publicKey: &ecTestKey256.PublicKey,
|
||||
}
|
||||
|
||||
if gen.keySize() != 16 {
|
||||
t.Error("ec key generator reported incorrect key size")
|
||||
}
|
||||
|
||||
_, _, err := gen.genKey()
|
||||
if err != nil {
|
||||
t.Error("ec key generator failed to generate key", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidECDecrypt(t *testing.T) {
|
||||
dec := ecDecrypterSigner{
|
||||
privateKey: ecTestKey256,
|
||||
}
|
||||
|
||||
generator := randomKeyGenerator{size: 16}
|
||||
|
||||
// Missing epk header
|
||||
headers := rawHeader{
|
||||
Alg: string(ECDH_ES),
|
||||
}
|
||||
|
||||
_, err := dec.decryptKey(headers, nil, generator)
|
||||
if err == nil {
|
||||
t.Error("ec decrypter accepted object with missing epk header")
|
||||
}
|
||||
|
||||
// Invalid epk header
|
||||
headers.Epk = &JSONWebKey{}
|
||||
|
||||
_, err = dec.decryptKey(headers, nil, generator)
|
||||
if err == nil {
|
||||
t.Error("ec decrypter accepted object with invalid epk header")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecryptWithIncorrectSize(t *testing.T) {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
dec := new(rsaDecrypterSigner)
|
||||
dec.privateKey = priv
|
||||
aes := newAESGCM(16)
|
||||
|
||||
keygen := randomKeyGenerator{
|
||||
size: aes.keySize(),
|
||||
}
|
||||
|
||||
payload := make([]byte, 254)
|
||||
_, err = dec.decrypt(payload, RSA1_5, keygen)
|
||||
if err == nil {
|
||||
t.Error("Invalid payload size should return error")
|
||||
}
|
||||
|
||||
payload = make([]byte, 257)
|
||||
_, err = dec.decrypt(payload, RSA1_5, keygen)
|
||||
if err == nil {
|
||||
t.Error("Invalid payload size should return error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPKCSDecryptNeverFails(t *testing.T) {
|
||||
// We don't want RSA-PKCS1 v1.5 decryption to ever fail, in order to prevent
|
||||
// side-channel timing attacks (Bleichenbacher attack in particular).
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
dec := new(rsaDecrypterSigner)
|
||||
dec.privateKey = priv
|
||||
aes := newAESGCM(16)
|
||||
|
||||
keygen := randomKeyGenerator{
|
||||
size: aes.keySize(),
|
||||
}
|
||||
|
||||
for i := 1; i < 50; i++ {
|
||||
payload := make([]byte, 256)
|
||||
_, err := io.ReadFull(rand.Reader, payload)
|
||||
if err != nil {
|
||||
t.Error("Unable to get random data:", err)
|
||||
return
|
||||
}
|
||||
_, err = dec.decrypt(payload, RSA1_5, keygen)
|
||||
if err != nil {
|
||||
t.Error("PKCS1v1.5 decrypt should never fail:", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPKCSDecryptWithValidPayloads(b *testing.B) {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
enc := new(rsaEncrypterVerifier)
|
||||
enc.publicKey = &priv.PublicKey
|
||||
dec := new(rsaDecrypterSigner)
|
||||
dec.privateKey = priv
|
||||
aes := newAESGCM(32)
|
||||
|
||||
b.StopTimer()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
plaintext := make([]byte, 32)
|
||||
_, err = io.ReadFull(rand.Reader, plaintext)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ciphertext, err := enc.encrypt(plaintext, RSA1_5)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
keygen := randomKeyGenerator{
|
||||
size: aes.keySize(),
|
||||
}
|
||||
|
||||
b.StartTimer()
|
||||
_, err = dec.decrypt(ciphertext, RSA1_5, keygen)
|
||||
b.StopTimer()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkPKCSDecryptWithInvalidPayloads(b *testing.B) {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
enc := new(rsaEncrypterVerifier)
|
||||
enc.publicKey = &priv.PublicKey
|
||||
dec := new(rsaDecrypterSigner)
|
||||
dec.privateKey = priv
|
||||
aes := newAESGCM(16)
|
||||
|
||||
keygen := randomKeyGenerator{
|
||||
size: aes.keySize(),
|
||||
}
|
||||
|
||||
b.StopTimer()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
plaintext := make([]byte, 16)
|
||||
_, err = io.ReadFull(rand.Reader, plaintext)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ciphertext, err := enc.encrypt(plaintext, RSA1_5)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Do some simple scrambling
|
||||
ciphertext[128] ^= 0xFF
|
||||
|
||||
b.StartTimer()
|
||||
_, err = dec.decrypt(ciphertext, RSA1_5, keygen)
|
||||
b.StopTimer()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidEllipticCurve(t *testing.T) {
|
||||
signer256 := ecDecrypterSigner{privateKey: ecTestKey256}
|
||||
signer384 := ecDecrypterSigner{privateKey: ecTestKey384}
|
||||
signer521 := ecDecrypterSigner{privateKey: ecTestKey521}
|
||||
|
||||
_, err := signer256.signPayload([]byte{}, ES384)
|
||||
if err == nil {
|
||||
t.Error("should not generate ES384 signature with P-256 key")
|
||||
}
|
||||
_, err = signer256.signPayload([]byte{}, ES512)
|
||||
if err == nil {
|
||||
t.Error("should not generate ES512 signature with P-256 key")
|
||||
}
|
||||
_, err = signer384.signPayload([]byte{}, ES256)
|
||||
if err == nil {
|
||||
t.Error("should not generate ES256 signature with P-384 key")
|
||||
}
|
||||
_, err = signer384.signPayload([]byte{}, ES512)
|
||||
if err == nil {
|
||||
t.Error("should not generate ES512 signature with P-384 key")
|
||||
}
|
||||
_, err = signer521.signPayload([]byte{}, ES256)
|
||||
if err == nil {
|
||||
t.Error("should not generate ES256 signature with P-521 key")
|
||||
}
|
||||
_, err = signer521.signPayload([]byte{}, ES384)
|
||||
if err == nil {
|
||||
t.Error("should not generate ES384 signature with P-521 key")
|
||||
}
|
||||
}
|
||||
|
||||
func estInvalidECPublicKey(t *testing.T) {
|
||||
// Invalid key
|
||||
invalid := &ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: elliptic.P256(),
|
||||
X: fromBase64Int("MTEx"),
|
||||
Y: fromBase64Int("MTEx"),
|
||||
},
|
||||
D: fromBase64Int("0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo"),
|
||||
}
|
||||
|
||||
headers := rawHeader{
|
||||
Alg: string(ECDH_ES),
|
||||
Epk: &JSONWebKey{
|
||||
Key: &invalid.PublicKey,
|
||||
},
|
||||
}
|
||||
|
||||
dec := ecDecrypterSigner{
|
||||
privateKey: ecTestKey256,
|
||||
}
|
||||
|
||||
_, err := dec.decryptKey(headers, nil, randomKeyGenerator{size: 16})
|
||||
if err == nil {
|
||||
t.Fatal("decrypter accepted JWS with invalid ECDH public key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidAlgorithmEC(t *testing.T) {
|
||||
err := ecEncrypterVerifier{publicKey: &ecTestKey256.PublicKey}.verifyPayload([]byte{}, []byte{}, "XYZ")
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Fatal("should not accept invalid/unsupported algorithm")
|
||||
}
|
||||
}
|
498
vendor/gopkg.in/square/go-jose.v2/cipher/cbc_hmac_test.go
generated
vendored
498
vendor/gopkg.in/square/go-jose.v2/cipher/cbc_hmac_test.go
generated
vendored
@@ -1,498 +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 josecipher
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInvalidInputs(t *testing.T) {
|
||||
key := []byte{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
}
|
||||
|
||||
nonce := []byte{
|
||||
92, 80, 104, 49, 133, 25, 161, 215, 173, 101, 219, 211, 136, 91, 210, 145}
|
||||
|
||||
aead, _ := NewCBCHMAC(key, aes.NewCipher)
|
||||
ciphertext := aead.Seal(nil, nonce, []byte("plaintext"), []byte("aad"))
|
||||
|
||||
// Changed AAD, must fail
|
||||
_, err := aead.Open(nil, nonce, ciphertext, []byte("INVALID"))
|
||||
if err == nil {
|
||||
t.Error("must detect invalid aad")
|
||||
}
|
||||
|
||||
// Empty ciphertext, must fail
|
||||
_, err = aead.Open(nil, nonce, []byte{}, []byte("aad"))
|
||||
if err == nil {
|
||||
t.Error("must detect invalid/empty ciphertext")
|
||||
}
|
||||
|
||||
// Corrupt ciphertext, must fail
|
||||
corrupt := make([]byte, len(ciphertext))
|
||||
copy(corrupt, ciphertext)
|
||||
corrupt[0] ^= 0xFF
|
||||
|
||||
_, err = aead.Open(nil, nonce, corrupt, []byte("aad"))
|
||||
if err == nil {
|
||||
t.Error("must detect corrupt ciphertext")
|
||||
}
|
||||
|
||||
// Corrupt authtag, must fail
|
||||
copy(corrupt, ciphertext)
|
||||
corrupt[len(ciphertext)-1] ^= 0xFF
|
||||
|
||||
_, err = aead.Open(nil, nonce, corrupt, []byte("aad"))
|
||||
if err == nil {
|
||||
t.Error("must detect corrupt authtag")
|
||||
}
|
||||
|
||||
// Truncated data, must fail
|
||||
_, err = aead.Open(nil, nonce, ciphertext[:10], []byte("aad"))
|
||||
if err == nil {
|
||||
t.Error("must detect corrupt authtag")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVectorsAESCBC128(t *testing.T) {
|
||||
// Source: http://tools.ietf.org/html/draft-ietf-jose-json-web-encryption-29#appendix-A.2
|
||||
plaintext := []byte{
|
||||
76, 105, 118, 101, 32, 108, 111, 110, 103, 32, 97, 110, 100, 32,
|
||||
112, 114, 111, 115, 112, 101, 114, 46}
|
||||
|
||||
aad := []byte{
|
||||
101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 83, 85, 48, 69,
|
||||
120, 88, 122, 85, 105, 76, 67, 74, 108, 98, 109, 77, 105, 79, 105,
|
||||
74, 66, 77, 84, 73, 52, 81, 48, 74, 68, 76, 85, 104, 84, 77, 106, 85,
|
||||
50, 73, 110, 48}
|
||||
|
||||
expectedCiphertext := []byte{
|
||||
40, 57, 83, 181, 119, 33, 133, 148, 198, 185, 243, 24, 152, 230, 6,
|
||||
75, 129, 223, 127, 19, 210, 82, 183, 230, 168, 33, 215, 104, 143,
|
||||
112, 56, 102}
|
||||
|
||||
expectedAuthtag := []byte{
|
||||
246, 17, 244, 190, 4, 95, 98, 3, 231, 0, 115, 157, 242, 203, 100,
|
||||
191}
|
||||
|
||||
key := []byte{
|
||||
4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106, 206,
|
||||
107, 124, 212, 45, 111, 107, 9, 219, 200, 177, 0, 240, 143, 156, 44, 207}
|
||||
|
||||
nonce := []byte{
|
||||
3, 22, 60, 12, 43, 67, 104, 105, 108, 108, 105, 99, 111, 116, 104, 101}
|
||||
|
||||
enc, err := NewCBCHMAC(key, aes.NewCipher)
|
||||
out := enc.Seal(nil, nonce, plaintext, aad)
|
||||
if err != nil {
|
||||
t.Error("Unable to encrypt:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if bytes.Compare(out[:len(out)-16], expectedCiphertext) != 0 {
|
||||
t.Error("Ciphertext did not match")
|
||||
}
|
||||
if bytes.Compare(out[len(out)-16:], expectedAuthtag) != 0 {
|
||||
t.Error("Auth tag did not match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVectorsAESCBC256(t *testing.T) {
|
||||
// Source: https://tools.ietf.org/html/draft-mcgrew-aead-aes-cbc-hmac-sha2-05#section-5.4
|
||||
plaintext := []byte{
|
||||
0x41, 0x20, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20,
|
||||
0x6d, 0x75, 0x73, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75,
|
||||
0x69, 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x63, 0x72, 0x65,
|
||||
0x74, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62,
|
||||
0x65, 0x20, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x61, 0x6c, 0x6c, 0x20, 0x69,
|
||||
0x6e, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x6f, 0x66,
|
||||
0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x65, 0x6d, 0x79, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f,
|
||||
0x75, 0x74, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x69, 0x65, 0x6e, 0x63, 0x65}
|
||||
|
||||
aad := []byte{
|
||||
0x54, 0x68, 0x65, 0x20, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x63,
|
||||
0x69, 0x70, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x65, 0x20,
|
||||
0x4b, 0x65, 0x72, 0x63, 0x6b, 0x68, 0x6f, 0x66, 0x66, 0x73}
|
||||
|
||||
expectedCiphertext := []byte{
|
||||
0x4a, 0xff, 0xaa, 0xad, 0xb7, 0x8c, 0x31, 0xc5, 0xda, 0x4b, 0x1b, 0x59, 0x0d, 0x10, 0xff, 0xbd,
|
||||
0x3d, 0xd8, 0xd5, 0xd3, 0x02, 0x42, 0x35, 0x26, 0x91, 0x2d, 0xa0, 0x37, 0xec, 0xbc, 0xc7, 0xbd,
|
||||
0x82, 0x2c, 0x30, 0x1d, 0xd6, 0x7c, 0x37, 0x3b, 0xcc, 0xb5, 0x84, 0xad, 0x3e, 0x92, 0x79, 0xc2,
|
||||
0xe6, 0xd1, 0x2a, 0x13, 0x74, 0xb7, 0x7f, 0x07, 0x75, 0x53, 0xdf, 0x82, 0x94, 0x10, 0x44, 0x6b,
|
||||
0x36, 0xeb, 0xd9, 0x70, 0x66, 0x29, 0x6a, 0xe6, 0x42, 0x7e, 0xa7, 0x5c, 0x2e, 0x08, 0x46, 0xa1,
|
||||
0x1a, 0x09, 0xcc, 0xf5, 0x37, 0x0d, 0xc8, 0x0b, 0xfe, 0xcb, 0xad, 0x28, 0xc7, 0x3f, 0x09, 0xb3,
|
||||
0xa3, 0xb7, 0x5e, 0x66, 0x2a, 0x25, 0x94, 0x41, 0x0a, 0xe4, 0x96, 0xb2, 0xe2, 0xe6, 0x60, 0x9e,
|
||||
0x31, 0xe6, 0xe0, 0x2c, 0xc8, 0x37, 0xf0, 0x53, 0xd2, 0x1f, 0x37, 0xff, 0x4f, 0x51, 0x95, 0x0b,
|
||||
0xbe, 0x26, 0x38, 0xd0, 0x9d, 0xd7, 0xa4, 0x93, 0x09, 0x30, 0x80, 0x6d, 0x07, 0x03, 0xb1, 0xf6}
|
||||
|
||||
expectedAuthtag := []byte{
|
||||
0x4d, 0xd3, 0xb4, 0xc0, 0x88, 0xa7, 0xf4, 0x5c, 0x21, 0x68, 0x39, 0x64, 0x5b, 0x20, 0x12, 0xbf,
|
||||
0x2e, 0x62, 0x69, 0xa8, 0xc5, 0x6a, 0x81, 0x6d, 0xbc, 0x1b, 0x26, 0x77, 0x61, 0x95, 0x5b, 0xc5}
|
||||
|
||||
key := []byte{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f}
|
||||
|
||||
nonce := []byte{
|
||||
0x1a, 0xf3, 0x8c, 0x2d, 0xc2, 0xb9, 0x6f, 0xfd, 0xd8, 0x66, 0x94, 0x09, 0x23, 0x41, 0xbc, 0x04}
|
||||
|
||||
enc, err := NewCBCHMAC(key, aes.NewCipher)
|
||||
out := enc.Seal(nil, nonce, plaintext, aad)
|
||||
if err != nil {
|
||||
t.Error("Unable to encrypt:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if bytes.Compare(out[:len(out)-32], expectedCiphertext) != 0 {
|
||||
t.Error("Ciphertext did not match, got", out[:len(out)-32], "wanted", expectedCiphertext)
|
||||
}
|
||||
if bytes.Compare(out[len(out)-32:], expectedAuthtag) != 0 {
|
||||
t.Error("Auth tag did not match, got", out[len(out)-32:], "wanted", expectedAuthtag)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAESCBCRoundtrip(t *testing.T) {
|
||||
key128 := []byte{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
|
||||
|
||||
key192 := []byte{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7}
|
||||
|
||||
key256 := []byte{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
|
||||
|
||||
nonce := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
|
||||
|
||||
RunRoundtrip(t, key128, nonce)
|
||||
RunRoundtrip(t, key192, nonce)
|
||||
RunRoundtrip(t, key256, nonce)
|
||||
}
|
||||
|
||||
func RunRoundtrip(t *testing.T, key, nonce []byte) {
|
||||
aead, err := NewCBCHMAC(key, aes.NewCipher)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if aead.NonceSize() != len(nonce) {
|
||||
panic("invalid nonce")
|
||||
}
|
||||
|
||||
// Test pre-existing data in dst buffer
|
||||
dst := []byte{15, 15, 15, 15}
|
||||
plaintext := []byte{0, 0, 0, 0}
|
||||
aad := []byte{4, 3, 2, 1}
|
||||
|
||||
result := aead.Seal(dst, nonce, plaintext, aad)
|
||||
if bytes.Compare(dst, result[:4]) != 0 {
|
||||
t.Error("Existing data in dst not preserved")
|
||||
}
|
||||
|
||||
// Test pre-existing (empty) dst buffer with sufficient capacity
|
||||
dst = make([]byte, 256)[:0]
|
||||
result, err = aead.Open(dst, nonce, result[4:], aad)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if bytes.Compare(result, plaintext) != 0 {
|
||||
t.Error("Plaintext does not match output")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAESCBCOverhead(t *testing.T) {
|
||||
aead, err := NewCBCHMAC(make([]byte, 32), aes.NewCipher)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if aead.Overhead() != 32 {
|
||||
t.Error("CBC-HMAC reports incorrect overhead value")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPadding(t *testing.T) {
|
||||
for i := 0; i < 256; i++ {
|
||||
slice := make([]byte, i)
|
||||
padded := padBuffer(slice, 16)
|
||||
if len(padded)%16 != 0 {
|
||||
t.Error("failed to pad slice properly", i)
|
||||
return
|
||||
}
|
||||
unpadded, err := unpadBuffer(padded, 16)
|
||||
if err != nil || len(unpadded) != i {
|
||||
t.Error("failed to unpad slice properly", i)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidKey(t *testing.T) {
|
||||
key := make([]byte, 30)
|
||||
_, err := NewCBCHMAC(key, aes.NewCipher)
|
||||
if err == nil {
|
||||
t.Error("should not be able to instantiate CBC-HMAC with invalid key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTruncatedCiphertext(t *testing.T) {
|
||||
key := make([]byte, 32)
|
||||
nonce := make([]byte, 16)
|
||||
data := make([]byte, 32)
|
||||
|
||||
io.ReadFull(rand.Reader, key)
|
||||
io.ReadFull(rand.Reader, nonce)
|
||||
|
||||
aead, err := NewCBCHMAC(key, aes.NewCipher)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ctx := aead.(*cbcAEAD)
|
||||
ct := aead.Seal(nil, nonce, data, nil)
|
||||
|
||||
// Truncated ciphertext, but with correct auth tag
|
||||
truncated, tail := resize(ct[:len(ct)-ctx.authtagBytes-2], uint64(len(ct))-2)
|
||||
copy(tail, ctx.computeAuthTag(nil, nonce, truncated[:len(truncated)-ctx.authtagBytes]))
|
||||
|
||||
// Open should fail
|
||||
_, err = aead.Open(nil, nonce, truncated, nil)
|
||||
if err == nil {
|
||||
t.Error("open on truncated ciphertext should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidPaddingOpen(t *testing.T) {
|
||||
key := make([]byte, 32)
|
||||
nonce := make([]byte, 16)
|
||||
|
||||
// Plaintext with invalid padding
|
||||
plaintext := padBuffer(make([]byte, 28), aes.BlockSize)
|
||||
plaintext[len(plaintext)-1] = 0xFF
|
||||
|
||||
io.ReadFull(rand.Reader, key)
|
||||
io.ReadFull(rand.Reader, nonce)
|
||||
|
||||
block, _ := aes.NewCipher(key)
|
||||
cbc := cipher.NewCBCEncrypter(block, nonce)
|
||||
buffer := append([]byte{}, plaintext...)
|
||||
cbc.CryptBlocks(buffer, buffer)
|
||||
|
||||
aead, _ := NewCBCHMAC(key, aes.NewCipher)
|
||||
ctx := aead.(*cbcAEAD)
|
||||
|
||||
// Mutated ciphertext, but with correct auth tag
|
||||
size := uint64(len(buffer))
|
||||
ciphertext, tail := resize(buffer, size+(uint64(len(key))/2))
|
||||
copy(tail, ctx.computeAuthTag(nil, nonce, ciphertext[:size]))
|
||||
|
||||
// Open should fail (b/c of invalid padding, even though tag matches)
|
||||
_, err := aead.Open(nil, nonce, ciphertext, nil)
|
||||
if err == nil || !strings.Contains(err.Error(), "invalid padding") {
|
||||
t.Error("no or unexpected error on open with invalid padding:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidPadding(t *testing.T) {
|
||||
for i := 0; i < 256; i++ {
|
||||
slice := make([]byte, i)
|
||||
padded := padBuffer(slice, 16)
|
||||
if len(padded)%16 != 0 {
|
||||
t.Error("failed to pad slice properly", i)
|
||||
return
|
||||
}
|
||||
|
||||
paddingBytes := 16 - (i % 16)
|
||||
|
||||
// Mutate padding for testing
|
||||
for j := 1; j <= paddingBytes; j++ {
|
||||
mutated := make([]byte, len(padded))
|
||||
copy(mutated, padded)
|
||||
mutated[len(mutated)-j] ^= 0xFF
|
||||
|
||||
_, err := unpadBuffer(mutated, 16)
|
||||
if err == nil {
|
||||
t.Error("unpad on invalid padding should fail", i)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Test truncated padding
|
||||
_, err := unpadBuffer(padded[:len(padded)-1], 16)
|
||||
if err == nil {
|
||||
t.Error("unpad on truncated padding should fail", i)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestZeroLengthPadding(t *testing.T) {
|
||||
data := make([]byte, 16)
|
||||
data, err := unpadBuffer(data, 16)
|
||||
if err == nil {
|
||||
t.Error("padding with 0x00 should never be valid")
|
||||
}
|
||||
}
|
||||
|
||||
func benchEncryptCBCHMAC(b *testing.B, keySize, chunkSize int) {
|
||||
key := make([]byte, keySize*2)
|
||||
nonce := make([]byte, 16)
|
||||
|
||||
io.ReadFull(rand.Reader, key)
|
||||
io.ReadFull(rand.Reader, nonce)
|
||||
|
||||
chunk := make([]byte, chunkSize)
|
||||
|
||||
aead, err := NewCBCHMAC(key, aes.NewCipher)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
b.SetBytes(int64(chunkSize))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
aead.Seal(nil, nonce, chunk, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func benchDecryptCBCHMAC(b *testing.B, keySize, chunkSize int) {
|
||||
key := make([]byte, keySize*2)
|
||||
nonce := make([]byte, 16)
|
||||
|
||||
io.ReadFull(rand.Reader, key)
|
||||
io.ReadFull(rand.Reader, nonce)
|
||||
|
||||
chunk := make([]byte, chunkSize)
|
||||
|
||||
aead, err := NewCBCHMAC(key, aes.NewCipher)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
out := aead.Seal(nil, nonce, chunk, nil)
|
||||
|
||||
b.SetBytes(int64(chunkSize))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
aead.Open(nil, nonce, out, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES128_CBCHMAC_1k(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 16, 1024)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES128_CBCHMAC_64k(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 16, 65536)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES128_CBCHMAC_1MB(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 16, 1048576)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES128_CBCHMAC_64MB(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 16, 67108864)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES128_CBCHMAC_1k(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 16, 1024)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES128_CBCHMAC_64k(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 16, 65536)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES128_CBCHMAC_1MB(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 16, 1048576)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES128_CBCHMAC_64MB(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 16, 67108864)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES192_CBCHMAC_64k(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 24, 65536)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES192_CBCHMAC_1MB(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 24, 1048576)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES192_CBCHMAC_64MB(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 24, 67108864)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES192_CBCHMAC_1k(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 24, 1024)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES192_CBCHMAC_64k(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 24, 65536)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES192_CBCHMAC_1MB(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 24, 1048576)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES192_CBCHMAC_64MB(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 24, 67108864)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES256_CBCHMAC_64k(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 32, 65536)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES256_CBCHMAC_1MB(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 32, 1048576)
|
||||
}
|
||||
|
||||
func BenchmarkEncryptAES256_CBCHMAC_64MB(b *testing.B) {
|
||||
benchEncryptCBCHMAC(b, 32, 67108864)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES256_CBCHMAC_1k(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 32, 1032)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES256_CBCHMAC_64k(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 32, 65536)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES256_CBCHMAC_1MB(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 32, 1048576)
|
||||
}
|
||||
|
||||
func BenchmarkDecryptAES256_CBCHMAC_64MB(b *testing.B) {
|
||||
benchDecryptCBCHMAC(b, 32, 67108864)
|
||||
}
|
150
vendor/gopkg.in/square/go-jose.v2/cipher/concat_kdf_test.go
generated
vendored
150
vendor/gopkg.in/square/go-jose.v2/cipher/concat_kdf_test.go
generated
vendored
@@ -1,150 +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 josecipher
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Taken from: https://tools.ietf.org/id/draft-ietf-jose-json-web-algorithms-38.txt
|
||||
func TestVectorConcatKDF(t *testing.T) {
|
||||
z := []byte{
|
||||
158, 86, 217, 29, 129, 113, 53, 211, 114, 131, 66, 131, 191, 132,
|
||||
38, 156, 251, 49, 110, 163, 218, 128, 106, 72, 246, 218, 167, 121,
|
||||
140, 254, 144, 196}
|
||||
|
||||
algID := []byte{0, 0, 0, 7, 65, 49, 50, 56, 71, 67, 77}
|
||||
|
||||
ptyUInfo := []byte{0, 0, 0, 5, 65, 108, 105, 99, 101}
|
||||
ptyVInfo := []byte{0, 0, 0, 3, 66, 111, 98}
|
||||
|
||||
supPubInfo := []byte{0, 0, 0, 128}
|
||||
supPrivInfo := []byte{}
|
||||
|
||||
expected := []byte{
|
||||
86, 170, 141, 234, 248, 35, 109, 32, 92, 34, 40, 205, 113, 167, 16, 26}
|
||||
|
||||
ckdf := NewConcatKDF(crypto.SHA256, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo)
|
||||
|
||||
out0 := make([]byte, 9)
|
||||
out1 := make([]byte, 7)
|
||||
|
||||
read0, err := ckdf.Read(out0)
|
||||
if err != nil {
|
||||
t.Error("error when reading from concat kdf reader", err)
|
||||
return
|
||||
}
|
||||
|
||||
read1, err := ckdf.Read(out1)
|
||||
if err != nil {
|
||||
t.Error("error when reading from concat kdf reader", err)
|
||||
return
|
||||
}
|
||||
|
||||
if read0+read1 != len(out0)+len(out1) {
|
||||
t.Error("did not receive enough bytes from concat kdf reader")
|
||||
return
|
||||
}
|
||||
|
||||
out := []byte{}
|
||||
out = append(out, out0...)
|
||||
out = append(out, out1...)
|
||||
|
||||
if bytes.Compare(out, expected) != 0 {
|
||||
t.Error("did not receive expected output from concat kdf reader")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestCache(t *testing.T) {
|
||||
z := []byte{
|
||||
158, 86, 217, 29, 129, 113, 53, 211, 114, 131, 66, 131, 191, 132,
|
||||
38, 156, 251, 49, 110, 163, 218, 128, 106, 72, 246, 218, 167, 121,
|
||||
140, 254, 144, 196}
|
||||
|
||||
algID := []byte{1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}
|
||||
|
||||
ptyUInfo := []byte{1, 2, 3, 4}
|
||||
ptyVInfo := []byte{4, 3, 2, 1}
|
||||
|
||||
supPubInfo := []byte{}
|
||||
supPrivInfo := []byte{}
|
||||
|
||||
outputs := [][]byte{}
|
||||
|
||||
// Read the same amount of data in different chunk sizes
|
||||
chunkSizes := []int{1, 2, 4, 8, 16, 32, 64, 128, 256, 512}
|
||||
|
||||
for _, c := range chunkSizes {
|
||||
out := make([]byte, 1024)
|
||||
reader := NewConcatKDF(crypto.SHA256, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo)
|
||||
|
||||
for i := 0; i < 1024; i += c {
|
||||
_, _ = reader.Read(out[i : i+c])
|
||||
}
|
||||
|
||||
outputs = append(outputs, out)
|
||||
}
|
||||
|
||||
for i := range outputs {
|
||||
if bytes.Compare(outputs[i], outputs[(i+1)%len(outputs)]) != 0 {
|
||||
t.Error("not all outputs from KDF matched")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkKDF(b *testing.B, total int) {
|
||||
z := []byte{
|
||||
158, 86, 217, 29, 129, 113, 53, 211, 114, 131, 66, 131, 191, 132,
|
||||
38, 156, 251, 49, 110, 163, 218, 128, 106, 72, 246, 218, 167, 121,
|
||||
140, 254, 144, 196}
|
||||
|
||||
algID := []byte{1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4}
|
||||
|
||||
ptyUInfo := []byte{1, 2, 3, 4}
|
||||
ptyVInfo := []byte{4, 3, 2, 1}
|
||||
|
||||
supPubInfo := []byte{}
|
||||
supPrivInfo := []byte{}
|
||||
|
||||
out := make([]byte, total)
|
||||
reader := NewConcatKDF(crypto.SHA256, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo)
|
||||
|
||||
b.ResetTimer()
|
||||
b.SetBytes(int64(total))
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, _ = reader.Read(out)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkConcatKDF_1k(b *testing.B) {
|
||||
benchmarkKDF(b, 1024)
|
||||
}
|
||||
|
||||
func BenchmarkConcatKDF_64k(b *testing.B) {
|
||||
benchmarkKDF(b, 65536)
|
||||
}
|
||||
|
||||
func BenchmarkConcatKDF_1MB(b *testing.B) {
|
||||
benchmarkKDF(b, 1048576)
|
||||
}
|
||||
|
||||
func BenchmarkConcatKDF_64MB(b *testing.B) {
|
||||
benchmarkKDF(b, 67108864)
|
||||
}
|
115
vendor/gopkg.in/square/go-jose.v2/cipher/ecdh_es_test.go
generated
vendored
115
vendor/gopkg.in/square/go-jose.v2/cipher/ecdh_es_test.go
generated
vendored
@@ -1,115 +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 josecipher
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"encoding/base64"
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Example keys from JWA, Appendix C
|
||||
var aliceKey = &ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: elliptic.P256(),
|
||||
X: fromBase64Int("gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0="),
|
||||
Y: fromBase64Int("SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps="),
|
||||
},
|
||||
D: fromBase64Int("0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo="),
|
||||
}
|
||||
|
||||
var bobKey = &ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: elliptic.P256(),
|
||||
X: fromBase64Int("weNJy2HscCSM6AEDTDg04biOvhFhyyWvOHQfeF_PxMQ="),
|
||||
Y: fromBase64Int("e8lnCO-AlStT-NJVX-crhB7QRYhiix03illJOVAOyck="),
|
||||
},
|
||||
D: fromBase64Int("VEmDZpDXXK8p8N0Cndsxs924q6nS1RXFASRl6BfUqdw="),
|
||||
}
|
||||
|
||||
// Build big int from base64-encoded string. Strips whitespace (for testing).
|
||||
func fromBase64Int(data string) *big.Int {
|
||||
val, err := base64.URLEncoding.DecodeString(data)
|
||||
if err != nil {
|
||||
panic("Invalid test data: " + err.Error())
|
||||
}
|
||||
return new(big.Int).SetBytes(val)
|
||||
}
|
||||
|
||||
func TestVectorECDHES(t *testing.T) {
|
||||
apuData := []byte("Alice")
|
||||
apvData := []byte("Bob")
|
||||
|
||||
expected := []byte{
|
||||
86, 170, 141, 234, 248, 35, 109, 32, 92, 34, 40, 205, 113, 167, 16, 26}
|
||||
|
||||
output := DeriveECDHES("A128GCM", apuData, apvData, bobKey, &aliceKey.PublicKey, 16)
|
||||
|
||||
if bytes.Compare(output, expected) != 0 {
|
||||
t.Error("output did not match what we expect, got", output, "wanted", expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidECPublicKey(t *testing.T) {
|
||||
defer func() { recover() }()
|
||||
|
||||
// Invalid key
|
||||
invalid := &ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: elliptic.P256(),
|
||||
X: fromBase64Int("MTEx"),
|
||||
Y: fromBase64Int("MTEx"),
|
||||
},
|
||||
D: fromBase64Int("0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo="),
|
||||
}
|
||||
|
||||
DeriveECDHES("A128GCM", []byte{}, []byte{}, bobKey, &invalid.PublicKey, 16)
|
||||
t.Fatal("should panic if public key was invalid")
|
||||
}
|
||||
|
||||
func BenchmarkECDHES_128(b *testing.B) {
|
||||
apuData := []byte("APU")
|
||||
apvData := []byte("APV")
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
DeriveECDHES("ID", apuData, apvData, bobKey, &aliceKey.PublicKey, 16)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkECDHES_192(b *testing.B) {
|
||||
apuData := []byte("APU")
|
||||
apvData := []byte("APV")
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
DeriveECDHES("ID", apuData, apvData, bobKey, &aliceKey.PublicKey, 24)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkECDHES_256(b *testing.B) {
|
||||
apuData := []byte("APU")
|
||||
apvData := []byte("APV")
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
DeriveECDHES("ID", apuData, apvData, bobKey, &aliceKey.PublicKey, 32)
|
||||
}
|
||||
}
|
133
vendor/gopkg.in/square/go-jose.v2/cipher/key_wrap_test.go
generated
vendored
133
vendor/gopkg.in/square/go-jose.v2/cipher/key_wrap_test.go
generated
vendored
@@ -1,133 +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 josecipher
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAesKeyWrap(t *testing.T) {
|
||||
// Test vectors from: http://csrc.nist.gov/groups/ST/toolkit/documents/kms/key-wrap.pdf
|
||||
kek0, _ := hex.DecodeString("000102030405060708090A0B0C0D0E0F")
|
||||
cek0, _ := hex.DecodeString("00112233445566778899AABBCCDDEEFF")
|
||||
|
||||
expected0, _ := hex.DecodeString("1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5")
|
||||
|
||||
kek1, _ := hex.DecodeString("000102030405060708090A0B0C0D0E0F1011121314151617")
|
||||
cek1, _ := hex.DecodeString("00112233445566778899AABBCCDDEEFF")
|
||||
|
||||
expected1, _ := hex.DecodeString("96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D")
|
||||
|
||||
kek2, _ := hex.DecodeString("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F")
|
||||
cek2, _ := hex.DecodeString("00112233445566778899AABBCCDDEEFF0001020304050607")
|
||||
|
||||
expected2, _ := hex.DecodeString("A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1")
|
||||
|
||||
block0, _ := aes.NewCipher(kek0)
|
||||
block1, _ := aes.NewCipher(kek1)
|
||||
block2, _ := aes.NewCipher(kek2)
|
||||
|
||||
out0, _ := KeyWrap(block0, cek0)
|
||||
out1, _ := KeyWrap(block1, cek1)
|
||||
out2, _ := KeyWrap(block2, cek2)
|
||||
|
||||
if bytes.Compare(out0, expected0) != 0 {
|
||||
t.Error("output 0 not as expected, got", out0, "wanted", expected0)
|
||||
}
|
||||
|
||||
if bytes.Compare(out1, expected1) != 0 {
|
||||
t.Error("output 1 not as expected, got", out1, "wanted", expected1)
|
||||
}
|
||||
|
||||
if bytes.Compare(out2, expected2) != 0 {
|
||||
t.Error("output 2 not as expected, got", out2, "wanted", expected2)
|
||||
}
|
||||
|
||||
unwrap0, _ := KeyUnwrap(block0, out0)
|
||||
unwrap1, _ := KeyUnwrap(block1, out1)
|
||||
unwrap2, _ := KeyUnwrap(block2, out2)
|
||||
|
||||
if bytes.Compare(unwrap0, cek0) != 0 {
|
||||
t.Error("key unwrap did not return original input, got", unwrap0, "wanted", cek0)
|
||||
}
|
||||
|
||||
if bytes.Compare(unwrap1, cek1) != 0 {
|
||||
t.Error("key unwrap did not return original input, got", unwrap1, "wanted", cek1)
|
||||
}
|
||||
|
||||
if bytes.Compare(unwrap2, cek2) != 0 {
|
||||
t.Error("key unwrap did not return original input, got", unwrap2, "wanted", cek2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAesKeyWrapInvalid(t *testing.T) {
|
||||
kek, _ := hex.DecodeString("000102030405060708090A0B0C0D0E0F")
|
||||
|
||||
// Invalid unwrap input (bit flipped)
|
||||
input0, _ := hex.DecodeString("1EA68C1A8112B447AEF34BD8FB5A7B828D3E862371D2CFE5")
|
||||
|
||||
block, _ := aes.NewCipher(kek)
|
||||
|
||||
_, err := KeyUnwrap(block, input0)
|
||||
if err == nil {
|
||||
t.Error("key unwrap failed to detect invalid input")
|
||||
}
|
||||
|
||||
// Invalid unwrap input (truncated)
|
||||
input1, _ := hex.DecodeString("1EA68C1A8112B447AEF34BD8FB5A7B828D3E862371D2CF")
|
||||
|
||||
_, err = KeyUnwrap(block, input1)
|
||||
if err == nil {
|
||||
t.Error("key unwrap failed to detect truncated input")
|
||||
}
|
||||
|
||||
// Invalid wrap input (not multiple of 8)
|
||||
input2, _ := hex.DecodeString("0123456789ABCD")
|
||||
|
||||
_, err = KeyWrap(block, input2)
|
||||
if err == nil {
|
||||
t.Error("key wrap accepted invalid input")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkAesKeyWrap(b *testing.B) {
|
||||
kek, _ := hex.DecodeString("000102030405060708090A0B0C0D0E0F")
|
||||
key, _ := hex.DecodeString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
|
||||
|
||||
block, _ := aes.NewCipher(kek)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
KeyWrap(block, key)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAesKeyUnwrap(b *testing.B) {
|
||||
kek, _ := hex.DecodeString("000102030405060708090A0B0C0D0E0F")
|
||||
input, _ := hex.DecodeString("1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5")
|
||||
|
||||
block, _ := aes.NewCipher(kek)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
KeyUnwrap(block, input)
|
||||
}
|
||||
}
|
755
vendor/gopkg.in/square/go-jose.v2/crypter_test.go
generated
vendored
755
vendor/gopkg.in/square/go-jose.v2/crypter_test.go
generated
vendored
@@ -1,755 +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 (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"fmt"
|
||||
"io"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// We generate only a single RSA and EC key for testing, speeds up tests.
|
||||
var rsaTestKey, _ = rsa.GenerateKey(rand.Reader, 2048)
|
||||
|
||||
var ecTestKey256, _ = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
var ecTestKey384, _ = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||
var ecTestKey521, _ = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
||||
|
||||
func RoundtripJWE(keyAlg KeyAlgorithm, encAlg ContentEncryption, compressionAlg CompressionAlgorithm, serializer func(*JSONWebEncryption) (string, error), corrupter func(*JSONWebEncryption) bool, aad []byte, encryptionKey interface{}, decryptionKey interface{}) error {
|
||||
enc, err := NewEncrypter(encAlg, Recipient{Algorithm: keyAlg, Key: encryptionKey}, &EncrypterOptions{Compression: compressionAlg})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error on new encrypter: %s", err)
|
||||
}
|
||||
|
||||
input := []byte("Lorem ipsum dolor sit amet")
|
||||
obj, err := enc.EncryptWithAuthData(input, aad)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error in encrypt: %s", err)
|
||||
}
|
||||
|
||||
msg, err := serializer(obj)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error in serializer: %s", err)
|
||||
}
|
||||
|
||||
parsed, err := ParseEncrypted(msg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error in parse: %s, on msg '%s'", err, msg)
|
||||
}
|
||||
|
||||
// (Maybe) mangle object
|
||||
skip := corrupter(parsed)
|
||||
if skip {
|
||||
return fmt.Errorf("corrupter indicated message should be skipped")
|
||||
}
|
||||
|
||||
if bytes.Compare(parsed.GetAuthData(), aad) != 0 {
|
||||
return fmt.Errorf("auth data in parsed object does not match")
|
||||
}
|
||||
|
||||
output, err := parsed.Decrypt(decryptionKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error on decrypt: %s", err)
|
||||
}
|
||||
|
||||
if bytes.Compare(input, output) != 0 {
|
||||
return fmt.Errorf("Decrypted output does not match input, got '%s' but wanted '%s'", output, input)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestRoundtripsJWE(t *testing.T) {
|
||||
// Test matrix
|
||||
keyAlgs := []KeyAlgorithm{
|
||||
DIRECT, ECDH_ES, ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW, A128KW, A192KW, A256KW,
|
||||
RSA1_5, RSA_OAEP, RSA_OAEP_256, A128GCMKW, A192GCMKW, A256GCMKW}
|
||||
encAlgs := []ContentEncryption{A128GCM, A192GCM, A256GCM, A128CBC_HS256, A192CBC_HS384, A256CBC_HS512}
|
||||
zipAlgs := []CompressionAlgorithm{NONE, DEFLATE}
|
||||
|
||||
serializers := []func(*JSONWebEncryption) (string, error){
|
||||
func(obj *JSONWebEncryption) (string, error) { return obj.CompactSerialize() },
|
||||
func(obj *JSONWebEncryption) (string, error) { return obj.FullSerialize(), nil },
|
||||
}
|
||||
|
||||
corrupter := func(obj *JSONWebEncryption) bool { return false }
|
||||
|
||||
// Note: can't use AAD with compact serialization
|
||||
aads := [][]byte{
|
||||
nil,
|
||||
[]byte("Ut enim ad minim veniam"),
|
||||
}
|
||||
|
||||
// Test all different configurations
|
||||
for _, alg := range keyAlgs {
|
||||
for _, enc := range encAlgs {
|
||||
for _, key := range generateTestKeys(alg, enc) {
|
||||
for _, zip := range zipAlgs {
|
||||
for i, serializer := range serializers {
|
||||
err := RoundtripJWE(alg, enc, zip, serializer, corrupter, aads[i], key.enc, key.dec)
|
||||
if err != nil {
|
||||
t.Error(err, alg, enc, zip, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoundtripsJWECorrupted(t *testing.T) {
|
||||
// Test matrix
|
||||
keyAlgs := []KeyAlgorithm{DIRECT, ECDH_ES, ECDH_ES_A128KW, A128KW, RSA1_5, RSA_OAEP, RSA_OAEP_256, A128GCMKW}
|
||||
encAlgs := []ContentEncryption{A128GCM, A192GCM, A256GCM, A128CBC_HS256, A192CBC_HS384, A256CBC_HS512}
|
||||
zipAlgs := []CompressionAlgorithm{NONE, DEFLATE}
|
||||
|
||||
serializers := []func(*JSONWebEncryption) (string, error){
|
||||
func(obj *JSONWebEncryption) (string, error) { return obj.CompactSerialize() },
|
||||
func(obj *JSONWebEncryption) (string, error) { return obj.FullSerialize(), nil },
|
||||
}
|
||||
|
||||
bitflip := func(slice []byte) bool {
|
||||
if len(slice) > 0 {
|
||||
slice[0] ^= 0xFF
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
corrupters := []func(*JSONWebEncryption) bool{
|
||||
func(obj *JSONWebEncryption) bool {
|
||||
// Set invalid ciphertext
|
||||
return bitflip(obj.ciphertext)
|
||||
},
|
||||
func(obj *JSONWebEncryption) bool {
|
||||
// Set invalid auth tag
|
||||
return bitflip(obj.tag)
|
||||
},
|
||||
func(obj *JSONWebEncryption) bool {
|
||||
// Set invalid AAD
|
||||
return bitflip(obj.aad)
|
||||
},
|
||||
func(obj *JSONWebEncryption) bool {
|
||||
// Mess with encrypted key
|
||||
return bitflip(obj.recipients[0].encryptedKey)
|
||||
},
|
||||
func(obj *JSONWebEncryption) bool {
|
||||
// Mess with GCM-KW auth tag
|
||||
return bitflip(obj.protected.Tag.bytes())
|
||||
},
|
||||
}
|
||||
|
||||
// Note: can't use AAD with compact serialization
|
||||
aads := [][]byte{
|
||||
nil,
|
||||
[]byte("Ut enim ad minim veniam"),
|
||||
}
|
||||
|
||||
// Test all different configurations
|
||||
for _, alg := range keyAlgs {
|
||||
for _, enc := range encAlgs {
|
||||
for _, key := range generateTestKeys(alg, enc) {
|
||||
for _, zip := range zipAlgs {
|
||||
for i, serializer := range serializers {
|
||||
for j, corrupter := range corrupters {
|
||||
err := RoundtripJWE(alg, enc, zip, serializer, corrupter, aads[i], key.enc, key.dec)
|
||||
if err == nil {
|
||||
t.Error("failed to detect corrupt data", err, alg, enc, zip, i, j)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncrypterWithJWKAndKeyID(t *testing.T) {
|
||||
enc, err := NewEncrypter(A128GCM, Recipient{Algorithm: A128KW, Key: &JSONWebKey{
|
||||
KeyID: "test-id",
|
||||
Key: []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
}}, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
ciphertext, _ := enc.Encrypt([]byte("Lorem ipsum dolor sit amet"))
|
||||
|
||||
serialized1, _ := ciphertext.CompactSerialize()
|
||||
serialized2 := ciphertext.FullSerialize()
|
||||
|
||||
parsed1, _ := ParseEncrypted(serialized1)
|
||||
parsed2, _ := ParseEncrypted(serialized2)
|
||||
|
||||
if parsed1.Header.KeyID != "test-id" {
|
||||
t.Errorf("expected message to have key id from JWK, but found '%s' instead", parsed1.Header.KeyID)
|
||||
}
|
||||
if parsed2.Header.KeyID != "test-id" {
|
||||
t.Errorf("expected message to have key id from JWK, but found '%s' instead", parsed2.Header.KeyID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncrypterWithBrokenRand(t *testing.T) {
|
||||
keyAlgs := []KeyAlgorithm{ECDH_ES_A128KW, A128KW, RSA1_5, RSA_OAEP, RSA_OAEP_256, A128GCMKW}
|
||||
encAlgs := []ContentEncryption{A128GCM, A192GCM, A256GCM, A128CBC_HS256, A192CBC_HS384, A256CBC_HS512}
|
||||
|
||||
serializer := func(obj *JSONWebEncryption) (string, error) { return obj.CompactSerialize() }
|
||||
corrupter := func(obj *JSONWebEncryption) bool { return false }
|
||||
|
||||
// Break rand reader
|
||||
readers := []func() io.Reader{
|
||||
// Totally broken
|
||||
func() io.Reader { return bytes.NewReader([]byte{}) },
|
||||
// Not enough bytes
|
||||
func() io.Reader { return io.LimitReader(rand.Reader, 20) },
|
||||
}
|
||||
|
||||
defer resetRandReader()
|
||||
|
||||
for _, alg := range keyAlgs {
|
||||
for _, enc := range encAlgs {
|
||||
for _, key := range generateTestKeys(alg, enc) {
|
||||
for i, getReader := range readers {
|
||||
randReader = getReader()
|
||||
err := RoundtripJWE(alg, enc, NONE, serializer, corrupter, nil, key.enc, key.dec)
|
||||
if err == nil {
|
||||
t.Error("encrypter should fail if rand is broken", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewEncrypterErrors(t *testing.T) {
|
||||
_, err := NewEncrypter("XYZ", Recipient{}, nil)
|
||||
if err == nil {
|
||||
t.Error("was able to instantiate encrypter with invalid cipher")
|
||||
}
|
||||
|
||||
_, err = NewMultiEncrypter("XYZ", []Recipient{}, nil)
|
||||
if err == nil {
|
||||
t.Error("was able to instantiate multi-encrypter with invalid cipher")
|
||||
}
|
||||
|
||||
_, err = NewEncrypter(A128GCM, Recipient{Algorithm: DIRECT, Key: nil}, nil)
|
||||
if err == nil {
|
||||
t.Error("was able to instantiate encrypter with invalid direct key")
|
||||
}
|
||||
|
||||
_, err = NewEncrypter(A128GCM, Recipient{Algorithm: ECDH_ES, Key: nil}, nil)
|
||||
if err == nil {
|
||||
t.Error("was able to instantiate encrypter with invalid EC key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiRecipientJWE(t *testing.T) {
|
||||
sharedKey := []byte{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
}
|
||||
|
||||
enc, err := NewMultiEncrypter(A128GCM, []Recipient{
|
||||
{Algorithm: RSA_OAEP, Key: &rsaTestKey.PublicKey},
|
||||
{Algorithm: A256GCMKW, Key: sharedKey},
|
||||
}, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
input := []byte("Lorem ipsum dolor sit amet")
|
||||
obj, err := enc.Encrypt(input)
|
||||
if err != nil {
|
||||
t.Fatal("error in encrypt: ", err)
|
||||
}
|
||||
|
||||
msg := obj.FullSerialize()
|
||||
|
||||
parsed, err := ParseEncrypted(msg)
|
||||
if err != nil {
|
||||
t.Fatal("error in parse: ", err)
|
||||
}
|
||||
|
||||
i, _, output, err := parsed.DecryptMulti(rsaTestKey)
|
||||
if err != nil {
|
||||
t.Fatal("error on decrypt with RSA: ", err)
|
||||
}
|
||||
|
||||
if i != 0 {
|
||||
t.Fatal("recipient index should be 0 for RSA key")
|
||||
}
|
||||
|
||||
if bytes.Compare(input, output) != 0 {
|
||||
t.Fatal("Decrypted output does not match input: ", output, input)
|
||||
}
|
||||
|
||||
i, _, output, err = parsed.DecryptMulti(sharedKey)
|
||||
if err != nil {
|
||||
t.Fatal("error on decrypt with AES: ", err)
|
||||
}
|
||||
|
||||
if i != 1 {
|
||||
t.Fatal("recipient index should be 1 for shared key")
|
||||
}
|
||||
|
||||
if bytes.Compare(input, output) != 0 {
|
||||
t.Fatal("Decrypted output does not match input", output, input)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiRecipientErrors(t *testing.T) {
|
||||
_, err := NewMultiEncrypter(A128GCM, []Recipient{}, nil)
|
||||
if err == nil {
|
||||
t.Error("should fail to instantiate with zero recipients")
|
||||
}
|
||||
}
|
||||
|
||||
type testKey struct {
|
||||
enc, dec interface{}
|
||||
}
|
||||
|
||||
func symmetricTestKey(size int) []testKey {
|
||||
key, _, _ := randomKeyGenerator{size: size}.genKey()
|
||||
|
||||
return []testKey{
|
||||
{
|
||||
enc: key,
|
||||
dec: key,
|
||||
},
|
||||
{
|
||||
enc: &JSONWebKey{KeyID: "test", Key: key},
|
||||
dec: &JSONWebKey{KeyID: "test", Key: key},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func generateTestKeys(keyAlg KeyAlgorithm, encAlg ContentEncryption) []testKey {
|
||||
switch keyAlg {
|
||||
case DIRECT:
|
||||
return symmetricTestKey(getContentCipher(encAlg).keySize())
|
||||
case ECDH_ES, ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW:
|
||||
return []testKey{
|
||||
{
|
||||
dec: ecTestKey256,
|
||||
enc: &ecTestKey256.PublicKey,
|
||||
},
|
||||
{
|
||||
dec: ecTestKey384,
|
||||
enc: &ecTestKey384.PublicKey,
|
||||
},
|
||||
{
|
||||
dec: ecTestKey521,
|
||||
enc: &ecTestKey521.PublicKey,
|
||||
},
|
||||
{
|
||||
dec: &JSONWebKey{KeyID: "test", Key: ecTestKey256},
|
||||
enc: &JSONWebKey{KeyID: "test", Key: &ecTestKey256.PublicKey},
|
||||
},
|
||||
}
|
||||
case A128GCMKW, A128KW:
|
||||
return symmetricTestKey(16)
|
||||
case A192GCMKW, A192KW:
|
||||
return symmetricTestKey(24)
|
||||
case A256GCMKW, A256KW:
|
||||
return symmetricTestKey(32)
|
||||
case RSA1_5, RSA_OAEP, RSA_OAEP_256:
|
||||
return []testKey{{
|
||||
dec: rsaTestKey,
|
||||
enc: &rsaTestKey.PublicKey,
|
||||
}}
|
||||
}
|
||||
|
||||
panic("Must update test case")
|
||||
}
|
||||
|
||||
func RunRoundtripsJWE(b *testing.B, alg KeyAlgorithm, enc ContentEncryption, zip CompressionAlgorithm, priv, pub interface{}) {
|
||||
serializer := func(obj *JSONWebEncryption) (string, error) {
|
||||
return obj.CompactSerialize()
|
||||
}
|
||||
|
||||
corrupter := func(obj *JSONWebEncryption) bool { return false }
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
err := RoundtripJWE(alg, enc, zip, serializer, corrupter, nil, pub, priv)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
chunks = map[string][]byte{
|
||||
"1B": make([]byte, 1),
|
||||
"64B": make([]byte, 64),
|
||||
"1KB": make([]byte, 1024),
|
||||
"64KB": make([]byte, 65536),
|
||||
"1MB": make([]byte, 1048576),
|
||||
"64MB": make([]byte, 67108864),
|
||||
}
|
||||
|
||||
symKey, _, _ = randomKeyGenerator{size: 32}.genKey()
|
||||
|
||||
encrypters = map[string]Encrypter{
|
||||
"OAEPAndGCM": mustEncrypter(RSA_OAEP, A128GCM, &rsaTestKey.PublicKey),
|
||||
"PKCSAndGCM": mustEncrypter(RSA1_5, A128GCM, &rsaTestKey.PublicKey),
|
||||
"OAEPAndCBC": mustEncrypter(RSA_OAEP, A128CBC_HS256, &rsaTestKey.PublicKey),
|
||||
"PKCSAndCBC": mustEncrypter(RSA1_5, A128CBC_HS256, &rsaTestKey.PublicKey),
|
||||
"DirectGCM128": mustEncrypter(DIRECT, A128GCM, symKey),
|
||||
"DirectCBC128": mustEncrypter(DIRECT, A128CBC_HS256, symKey),
|
||||
"DirectGCM256": mustEncrypter(DIRECT, A256GCM, symKey),
|
||||
"DirectCBC256": mustEncrypter(DIRECT, A256CBC_HS512, symKey),
|
||||
"AESKWAndGCM128": mustEncrypter(A128KW, A128GCM, symKey),
|
||||
"AESKWAndCBC256": mustEncrypter(A256KW, A256GCM, symKey),
|
||||
"ECDHOnP256AndGCM128": mustEncrypter(ECDH_ES, A128GCM, &ecTestKey256.PublicKey),
|
||||
"ECDHOnP384AndGCM128": mustEncrypter(ECDH_ES, A128GCM, &ecTestKey384.PublicKey),
|
||||
"ECDHOnP521AndGCM128": mustEncrypter(ECDH_ES, A128GCM, &ecTestKey521.PublicKey),
|
||||
}
|
||||
)
|
||||
|
||||
func BenchmarkEncrypt1BWithOAEPAndGCM(b *testing.B) { benchEncrypt("1B", "OAEPAndGCM", b) }
|
||||
func BenchmarkEncrypt64BWithOAEPAndGCM(b *testing.B) { benchEncrypt("64B", "OAEPAndGCM", b) }
|
||||
func BenchmarkEncrypt1KBWithOAEPAndGCM(b *testing.B) { benchEncrypt("1KB", "OAEPAndGCM", b) }
|
||||
func BenchmarkEncrypt64KBWithOAEPAndGCM(b *testing.B) { benchEncrypt("64KB", "OAEPAndGCM", b) }
|
||||
func BenchmarkEncrypt1MBWithOAEPAndGCM(b *testing.B) { benchEncrypt("1MB", "OAEPAndGCM", b) }
|
||||
func BenchmarkEncrypt64MBWithOAEPAndGCM(b *testing.B) { benchEncrypt("64MB", "OAEPAndGCM", b) }
|
||||
|
||||
func BenchmarkEncrypt1BWithPKCSAndGCM(b *testing.B) { benchEncrypt("1B", "PKCSAndGCM", b) }
|
||||
func BenchmarkEncrypt64BWithPKCSAndGCM(b *testing.B) { benchEncrypt("64B", "PKCSAndGCM", b) }
|
||||
func BenchmarkEncrypt1KBWithPKCSAndGCM(b *testing.B) { benchEncrypt("1KB", "PKCSAndGCM", b) }
|
||||
func BenchmarkEncrypt64KBWithPKCSAndGCM(b *testing.B) { benchEncrypt("64KB", "PKCSAndGCM", b) }
|
||||
func BenchmarkEncrypt1MBWithPKCSAndGCM(b *testing.B) { benchEncrypt("1MB", "PKCSAndGCM", b) }
|
||||
func BenchmarkEncrypt64MBWithPKCSAndGCM(b *testing.B) { benchEncrypt("64MB", "PKCSAndGCM", b) }
|
||||
|
||||
func BenchmarkEncrypt1BWithOAEPAndCBC(b *testing.B) { benchEncrypt("1B", "OAEPAndCBC", b) }
|
||||
func BenchmarkEncrypt64BWithOAEPAndCBC(b *testing.B) { benchEncrypt("64B", "OAEPAndCBC", b) }
|
||||
func BenchmarkEncrypt1KBWithOAEPAndCBC(b *testing.B) { benchEncrypt("1KB", "OAEPAndCBC", b) }
|
||||
func BenchmarkEncrypt64KBWithOAEPAndCBC(b *testing.B) { benchEncrypt("64KB", "OAEPAndCBC", b) }
|
||||
func BenchmarkEncrypt1MBWithOAEPAndCBC(b *testing.B) { benchEncrypt("1MB", "OAEPAndCBC", b) }
|
||||
func BenchmarkEncrypt64MBWithOAEPAndCBC(b *testing.B) { benchEncrypt("64MB", "OAEPAndCBC", b) }
|
||||
|
||||
func BenchmarkEncrypt1BWithPKCSAndCBC(b *testing.B) { benchEncrypt("1B", "PKCSAndCBC", b) }
|
||||
func BenchmarkEncrypt64BWithPKCSAndCBC(b *testing.B) { benchEncrypt("64B", "PKCSAndCBC", b) }
|
||||
func BenchmarkEncrypt1KBWithPKCSAndCBC(b *testing.B) { benchEncrypt("1KB", "PKCSAndCBC", b) }
|
||||
func BenchmarkEncrypt64KBWithPKCSAndCBC(b *testing.B) { benchEncrypt("64KB", "PKCSAndCBC", b) }
|
||||
func BenchmarkEncrypt1MBWithPKCSAndCBC(b *testing.B) { benchEncrypt("1MB", "PKCSAndCBC", b) }
|
||||
func BenchmarkEncrypt64MBWithPKCSAndCBC(b *testing.B) { benchEncrypt("64MB", "PKCSAndCBC", b) }
|
||||
|
||||
func BenchmarkEncrypt1BWithDirectGCM128(b *testing.B) { benchEncrypt("1B", "DirectGCM128", b) }
|
||||
func BenchmarkEncrypt64BWithDirectGCM128(b *testing.B) { benchEncrypt("64B", "DirectGCM128", b) }
|
||||
func BenchmarkEncrypt1KBWithDirectGCM128(b *testing.B) { benchEncrypt("1KB", "DirectGCM128", b) }
|
||||
func BenchmarkEncrypt64KBWithDirectGCM128(b *testing.B) { benchEncrypt("64KB", "DirectGCM128", b) }
|
||||
func BenchmarkEncrypt1MBWithDirectGCM128(b *testing.B) { benchEncrypt("1MB", "DirectGCM128", b) }
|
||||
func BenchmarkEncrypt64MBWithDirectGCM128(b *testing.B) { benchEncrypt("64MB", "DirectGCM128", b) }
|
||||
|
||||
func BenchmarkEncrypt1BWithDirectCBC128(b *testing.B) { benchEncrypt("1B", "DirectCBC128", b) }
|
||||
func BenchmarkEncrypt64BWithDirectCBC128(b *testing.B) { benchEncrypt("64B", "DirectCBC128", b) }
|
||||
func BenchmarkEncrypt1KBWithDirectCBC128(b *testing.B) { benchEncrypt("1KB", "DirectCBC128", b) }
|
||||
func BenchmarkEncrypt64KBWithDirectCBC128(b *testing.B) { benchEncrypt("64KB", "DirectCBC128", b) }
|
||||
func BenchmarkEncrypt1MBWithDirectCBC128(b *testing.B) { benchEncrypt("1MB", "DirectCBC128", b) }
|
||||
func BenchmarkEncrypt64MBWithDirectCBC128(b *testing.B) { benchEncrypt("64MB", "DirectCBC128", b) }
|
||||
|
||||
func BenchmarkEncrypt1BWithDirectGCM256(b *testing.B) { benchEncrypt("1B", "DirectGCM256", b) }
|
||||
func BenchmarkEncrypt64BWithDirectGCM256(b *testing.B) { benchEncrypt("64B", "DirectGCM256", b) }
|
||||
func BenchmarkEncrypt1KBWithDirectGCM256(b *testing.B) { benchEncrypt("1KB", "DirectGCM256", b) }
|
||||
func BenchmarkEncrypt64KBWithDirectGCM256(b *testing.B) { benchEncrypt("64KB", "DirectGCM256", b) }
|
||||
func BenchmarkEncrypt1MBWithDirectGCM256(b *testing.B) { benchEncrypt("1MB", "DirectGCM256", b) }
|
||||
func BenchmarkEncrypt64MBWithDirectGCM256(b *testing.B) { benchEncrypt("64MB", "DirectGCM256", b) }
|
||||
|
||||
func BenchmarkEncrypt1BWithDirectCBC256(b *testing.B) { benchEncrypt("1B", "DirectCBC256", b) }
|
||||
func BenchmarkEncrypt64BWithDirectCBC256(b *testing.B) { benchEncrypt("64B", "DirectCBC256", b) }
|
||||
func BenchmarkEncrypt1KBWithDirectCBC256(b *testing.B) { benchEncrypt("1KB", "DirectCBC256", b) }
|
||||
func BenchmarkEncrypt64KBWithDirectCBC256(b *testing.B) { benchEncrypt("64KB", "DirectCBC256", b) }
|
||||
func BenchmarkEncrypt1MBWithDirectCBC256(b *testing.B) { benchEncrypt("1MB", "DirectCBC256", b) }
|
||||
func BenchmarkEncrypt64MBWithDirectCBC256(b *testing.B) { benchEncrypt("64MB", "DirectCBC256", b) }
|
||||
|
||||
func BenchmarkEncrypt1BWithAESKWAndGCM128(b *testing.B) { benchEncrypt("1B", "AESKWAndGCM128", b) }
|
||||
func BenchmarkEncrypt64BWithAESKWAndGCM128(b *testing.B) { benchEncrypt("64B", "AESKWAndGCM128", b) }
|
||||
func BenchmarkEncrypt1KBWithAESKWAndGCM128(b *testing.B) { benchEncrypt("1KB", "AESKWAndGCM128", b) }
|
||||
func BenchmarkEncrypt64KBWithAESKWAndGCM128(b *testing.B) { benchEncrypt("64KB", "AESKWAndGCM128", b) }
|
||||
func BenchmarkEncrypt1MBWithAESKWAndGCM128(b *testing.B) { benchEncrypt("1MB", "AESKWAndGCM128", b) }
|
||||
func BenchmarkEncrypt64MBWithAESKWAndGCM128(b *testing.B) { benchEncrypt("64MB", "AESKWAndGCM128", b) }
|
||||
|
||||
func BenchmarkEncrypt1BWithAESKWAndCBC256(b *testing.B) { benchEncrypt("1B", "AESKWAndCBC256", b) }
|
||||
func BenchmarkEncrypt64BWithAESKWAndCBC256(b *testing.B) { benchEncrypt("64B", "AESKWAndCBC256", b) }
|
||||
func BenchmarkEncrypt1KBWithAESKWAndCBC256(b *testing.B) { benchEncrypt("1KB", "AESKWAndCBC256", b) }
|
||||
func BenchmarkEncrypt64KBWithAESKWAndCBC256(b *testing.B) { benchEncrypt("64KB", "AESKWAndCBC256", b) }
|
||||
func BenchmarkEncrypt1MBWithAESKWAndCBC256(b *testing.B) { benchEncrypt("1MB", "AESKWAndCBC256", b) }
|
||||
func BenchmarkEncrypt64MBWithAESKWAndCBC256(b *testing.B) { benchEncrypt("64MB", "AESKWAndCBC256", b) }
|
||||
|
||||
func BenchmarkEncrypt1BWithECDHOnP256AndGCM128(b *testing.B) {
|
||||
benchEncrypt("1B", "ECDHOnP256AndGCM128", b)
|
||||
}
|
||||
func BenchmarkEncrypt64BWithECDHOnP256AndGCM128(b *testing.B) {
|
||||
benchEncrypt("64B", "ECDHOnP256AndGCM128", b)
|
||||
}
|
||||
func BenchmarkEncrypt1KBWithECDHOnP256AndGCM128(b *testing.B) {
|
||||
benchEncrypt("1KB", "ECDHOnP256AndGCM128", b)
|
||||
}
|
||||
func BenchmarkEncrypt64KBWithECDHOnP256AndGCM128(b *testing.B) {
|
||||
benchEncrypt("64KB", "ECDHOnP256AndGCM128", b)
|
||||
}
|
||||
func BenchmarkEncrypt1MBWithECDHOnP256AndGCM128(b *testing.B) {
|
||||
benchEncrypt("1MB", "ECDHOnP256AndGCM128", b)
|
||||
}
|
||||
func BenchmarkEncrypt64MBWithECDHOnP256AndGCM128(b *testing.B) {
|
||||
benchEncrypt("64MB", "ECDHOnP256AndGCM128", b)
|
||||
}
|
||||
|
||||
func BenchmarkEncrypt1BWithECDHOnP384AndGCM128(b *testing.B) {
|
||||
benchEncrypt("1B", "ECDHOnP384AndGCM128", b)
|
||||
}
|
||||
func BenchmarkEncrypt64BWithECDHOnP384AndGCM128(b *testing.B) {
|
||||
benchEncrypt("64B", "ECDHOnP384AndGCM128", b)
|
||||
}
|
||||
func BenchmarkEncrypt1KBWithECDHOnP384AndGCM128(b *testing.B) {
|
||||
benchEncrypt("1KB", "ECDHOnP384AndGCM128", b)
|
||||
}
|
||||
func BenchmarkEncrypt64KBWithECDHOnP384AndGCM128(b *testing.B) {
|
||||
benchEncrypt("64KB", "ECDHOnP384AndGCM128", b)
|
||||
}
|
||||
func BenchmarkEncrypt1MBWithECDHOnP384AndGCM128(b *testing.B) {
|
||||
benchEncrypt("1MB", "ECDHOnP384AndGCM128", b)
|
||||
}
|
||||
func BenchmarkEncrypt64MBWithECDHOnP384AndGCM128(b *testing.B) {
|
||||
benchEncrypt("64MB", "ECDHOnP384AndGCM128", b)
|
||||
}
|
||||
|
||||
func BenchmarkEncrypt1BWithECDHOnP521AndGCM128(b *testing.B) {
|
||||
benchEncrypt("1B", "ECDHOnP521AndGCM128", b)
|
||||
}
|
||||
func BenchmarkEncrypt64BWithECDHOnP521AndGCM128(b *testing.B) {
|
||||
benchEncrypt("64B", "ECDHOnP521AndGCM128", b)
|
||||
}
|
||||
func BenchmarkEncrypt1KBWithECDHOnP521AndGCM128(b *testing.B) {
|
||||
benchEncrypt("1KB", "ECDHOnP521AndGCM128", b)
|
||||
}
|
||||
func BenchmarkEncrypt64KBWithECDHOnP521AndGCM128(b *testing.B) {
|
||||
benchEncrypt("64KB", "ECDHOnP521AndGCM128", b)
|
||||
}
|
||||
func BenchmarkEncrypt1MBWithECDHOnP521AndGCM128(b *testing.B) {
|
||||
benchEncrypt("1MB", "ECDHOnP521AndGCM128", b)
|
||||
}
|
||||
func BenchmarkEncrypt64MBWithECDHOnP521AndGCM128(b *testing.B) {
|
||||
benchEncrypt("64MB", "ECDHOnP521AndGCM128", b)
|
||||
}
|
||||
|
||||
func benchEncrypt(chunkKey, primKey string, b *testing.B) {
|
||||
data, ok := chunks[chunkKey]
|
||||
if !ok {
|
||||
b.Fatalf("unknown chunk size %s", chunkKey)
|
||||
}
|
||||
|
||||
enc, ok := encrypters[primKey]
|
||||
if !ok {
|
||||
b.Fatalf("unknown encrypter %s", primKey)
|
||||
}
|
||||
|
||||
b.SetBytes(int64(len(data)))
|
||||
for i := 0; i < b.N; i++ {
|
||||
enc.Encrypt(data)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
decryptionKeys = map[string]interface{}{
|
||||
"OAEPAndGCM": rsaTestKey,
|
||||
"PKCSAndGCM": rsaTestKey,
|
||||
"OAEPAndCBC": rsaTestKey,
|
||||
"PKCSAndCBC": rsaTestKey,
|
||||
|
||||
"DirectGCM128": symKey,
|
||||
"DirectCBC128": symKey,
|
||||
"DirectGCM256": symKey,
|
||||
"DirectCBC256": symKey,
|
||||
|
||||
"AESKWAndGCM128": symKey,
|
||||
"AESKWAndCBC256": symKey,
|
||||
|
||||
"ECDHOnP256AndGCM128": ecTestKey256,
|
||||
"ECDHOnP384AndGCM128": ecTestKey384,
|
||||
"ECDHOnP521AndGCM128": ecTestKey521,
|
||||
}
|
||||
)
|
||||
|
||||
func BenchmarkDecrypt1BWithOAEPAndGCM(b *testing.B) { benchDecrypt("1B", "OAEPAndGCM", b) }
|
||||
func BenchmarkDecrypt64BWithOAEPAndGCM(b *testing.B) { benchDecrypt("64B", "OAEPAndGCM", b) }
|
||||
func BenchmarkDecrypt1KBWithOAEPAndGCM(b *testing.B) { benchDecrypt("1KB", "OAEPAndGCM", b) }
|
||||
func BenchmarkDecrypt64KBWithOAEPAndGCM(b *testing.B) { benchDecrypt("64KB", "OAEPAndGCM", b) }
|
||||
func BenchmarkDecrypt1MBWithOAEPAndGCM(b *testing.B) { benchDecrypt("1MB", "OAEPAndGCM", b) }
|
||||
func BenchmarkDecrypt64MBWithOAEPAndGCM(b *testing.B) { benchDecrypt("64MB", "OAEPAndGCM", b) }
|
||||
|
||||
func BenchmarkDecrypt1BWithPKCSAndGCM(b *testing.B) { benchDecrypt("1B", "PKCSAndGCM", b) }
|
||||
func BenchmarkDecrypt64BWithPKCSAndGCM(b *testing.B) { benchDecrypt("64B", "PKCSAndGCM", b) }
|
||||
func BenchmarkDecrypt1KBWithPKCSAndGCM(b *testing.B) { benchDecrypt("1KB", "PKCSAndGCM", b) }
|
||||
func BenchmarkDecrypt64KBWithPKCSAndGCM(b *testing.B) { benchDecrypt("64KB", "PKCSAndGCM", b) }
|
||||
func BenchmarkDecrypt1MBWithPKCSAndGCM(b *testing.B) { benchDecrypt("1MB", "PKCSAndGCM", b) }
|
||||
func BenchmarkDecrypt64MBWithPKCSAndGCM(b *testing.B) { benchDecrypt("64MB", "PKCSAndGCM", b) }
|
||||
|
||||
func BenchmarkDecrypt1BWithOAEPAndCBC(b *testing.B) { benchDecrypt("1B", "OAEPAndCBC", b) }
|
||||
func BenchmarkDecrypt64BWithOAEPAndCBC(b *testing.B) { benchDecrypt("64B", "OAEPAndCBC", b) }
|
||||
func BenchmarkDecrypt1KBWithOAEPAndCBC(b *testing.B) { benchDecrypt("1KB", "OAEPAndCBC", b) }
|
||||
func BenchmarkDecrypt64KBWithOAEPAndCBC(b *testing.B) { benchDecrypt("64KB", "OAEPAndCBC", b) }
|
||||
func BenchmarkDecrypt1MBWithOAEPAndCBC(b *testing.B) { benchDecrypt("1MB", "OAEPAndCBC", b) }
|
||||
func BenchmarkDecrypt64MBWithOAEPAndCBC(b *testing.B) { benchDecrypt("64MB", "OAEPAndCBC", b) }
|
||||
|
||||
func BenchmarkDecrypt1BWithPKCSAndCBC(b *testing.B) { benchDecrypt("1B", "PKCSAndCBC", b) }
|
||||
func BenchmarkDecrypt64BWithPKCSAndCBC(b *testing.B) { benchDecrypt("64B", "PKCSAndCBC", b) }
|
||||
func BenchmarkDecrypt1KBWithPKCSAndCBC(b *testing.B) { benchDecrypt("1KB", "PKCSAndCBC", b) }
|
||||
func BenchmarkDecrypt64KBWithPKCSAndCBC(b *testing.B) { benchDecrypt("64KB", "PKCSAndCBC", b) }
|
||||
func BenchmarkDecrypt1MBWithPKCSAndCBC(b *testing.B) { benchDecrypt("1MB", "PKCSAndCBC", b) }
|
||||
func BenchmarkDecrypt64MBWithPKCSAndCBC(b *testing.B) { benchDecrypt("64MB", "PKCSAndCBC", b) }
|
||||
|
||||
func BenchmarkDecrypt1BWithDirectGCM128(b *testing.B) { benchDecrypt("1B", "DirectGCM128", b) }
|
||||
func BenchmarkDecrypt64BWithDirectGCM128(b *testing.B) { benchDecrypt("64B", "DirectGCM128", b) }
|
||||
func BenchmarkDecrypt1KBWithDirectGCM128(b *testing.B) { benchDecrypt("1KB", "DirectGCM128", b) }
|
||||
func BenchmarkDecrypt64KBWithDirectGCM128(b *testing.B) { benchDecrypt("64KB", "DirectGCM128", b) }
|
||||
func BenchmarkDecrypt1MBWithDirectGCM128(b *testing.B) { benchDecrypt("1MB", "DirectGCM128", b) }
|
||||
func BenchmarkDecrypt64MBWithDirectGCM128(b *testing.B) { benchDecrypt("64MB", "DirectGCM128", b) }
|
||||
|
||||
func BenchmarkDecrypt1BWithDirectCBC128(b *testing.B) { benchDecrypt("1B", "DirectCBC128", b) }
|
||||
func BenchmarkDecrypt64BWithDirectCBC128(b *testing.B) { benchDecrypt("64B", "DirectCBC128", b) }
|
||||
func BenchmarkDecrypt1KBWithDirectCBC128(b *testing.B) { benchDecrypt("1KB", "DirectCBC128", b) }
|
||||
func BenchmarkDecrypt64KBWithDirectCBC128(b *testing.B) { benchDecrypt("64KB", "DirectCBC128", b) }
|
||||
func BenchmarkDecrypt1MBWithDirectCBC128(b *testing.B) { benchDecrypt("1MB", "DirectCBC128", b) }
|
||||
func BenchmarkDecrypt64MBWithDirectCBC128(b *testing.B) { benchDecrypt("64MB", "DirectCBC128", b) }
|
||||
|
||||
func BenchmarkDecrypt1BWithDirectGCM256(b *testing.B) { benchDecrypt("1B", "DirectGCM256", b) }
|
||||
func BenchmarkDecrypt64BWithDirectGCM256(b *testing.B) { benchDecrypt("64B", "DirectGCM256", b) }
|
||||
func BenchmarkDecrypt1KBWithDirectGCM256(b *testing.B) { benchDecrypt("1KB", "DirectGCM256", b) }
|
||||
func BenchmarkDecrypt64KBWithDirectGCM256(b *testing.B) { benchDecrypt("64KB", "DirectGCM256", b) }
|
||||
func BenchmarkDecrypt1MBWithDirectGCM256(b *testing.B) { benchDecrypt("1MB", "DirectGCM256", b) }
|
||||
func BenchmarkDecrypt64MBWithDirectGCM256(b *testing.B) { benchDecrypt("64MB", "DirectGCM256", b) }
|
||||
|
||||
func BenchmarkDecrypt1BWithDirectCBC256(b *testing.B) { benchDecrypt("1B", "DirectCBC256", b) }
|
||||
func BenchmarkDecrypt64BWithDirectCBC256(b *testing.B) { benchDecrypt("64B", "DirectCBC256", b) }
|
||||
func BenchmarkDecrypt1KBWithDirectCBC256(b *testing.B) { benchDecrypt("1KB", "DirectCBC256", b) }
|
||||
func BenchmarkDecrypt64KBWithDirectCBC256(b *testing.B) { benchDecrypt("64KB", "DirectCBC256", b) }
|
||||
func BenchmarkDecrypt1MBWithDirectCBC256(b *testing.B) { benchDecrypt("1MB", "DirectCBC256", b) }
|
||||
func BenchmarkDecrypt64MBWithDirectCBC256(b *testing.B) { benchDecrypt("64MB", "DirectCBC256", b) }
|
||||
|
||||
func BenchmarkDecrypt1BWithAESKWAndGCM128(b *testing.B) { benchDecrypt("1B", "AESKWAndGCM128", b) }
|
||||
func BenchmarkDecrypt64BWithAESKWAndGCM128(b *testing.B) { benchDecrypt("64B", "AESKWAndGCM128", b) }
|
||||
func BenchmarkDecrypt1KBWithAESKWAndGCM128(b *testing.B) { benchDecrypt("1KB", "AESKWAndGCM128", b) }
|
||||
func BenchmarkDecrypt64KBWithAESKWAndGCM128(b *testing.B) { benchDecrypt("64KB", "AESKWAndGCM128", b) }
|
||||
func BenchmarkDecrypt1MBWithAESKWAndGCM128(b *testing.B) { benchDecrypt("1MB", "AESKWAndGCM128", b) }
|
||||
func BenchmarkDecrypt64MBWithAESKWAndGCM128(b *testing.B) { benchDecrypt("64MB", "AESKWAndGCM128", b) }
|
||||
|
||||
func BenchmarkDecrypt1BWithAESKWAndCBC256(b *testing.B) { benchDecrypt("1B", "AESKWAndCBC256", b) }
|
||||
func BenchmarkDecrypt64BWithAESKWAndCBC256(b *testing.B) { benchDecrypt("64B", "AESKWAndCBC256", b) }
|
||||
func BenchmarkDecrypt1KBWithAESKWAndCBC256(b *testing.B) { benchDecrypt("1KB", "AESKWAndCBC256", b) }
|
||||
func BenchmarkDecrypt64KBWithAESKWAndCBC256(b *testing.B) { benchDecrypt("64KB", "AESKWAndCBC256", b) }
|
||||
func BenchmarkDecrypt1MBWithAESKWAndCBC256(b *testing.B) { benchDecrypt("1MB", "AESKWAndCBC256", b) }
|
||||
func BenchmarkDecrypt64MBWithAESKWAndCBC256(b *testing.B) { benchDecrypt("64MB", "AESKWAndCBC256", b) }
|
||||
|
||||
func BenchmarkDecrypt1BWithECDHOnP256AndGCM128(b *testing.B) {
|
||||
benchDecrypt("1B", "ECDHOnP256AndGCM128", b)
|
||||
}
|
||||
func BenchmarkDecrypt64BWithECDHOnP256AndGCM128(b *testing.B) {
|
||||
benchDecrypt("64B", "ECDHOnP256AndGCM128", b)
|
||||
}
|
||||
func BenchmarkDecrypt1KBWithECDHOnP256AndGCM128(b *testing.B) {
|
||||
benchDecrypt("1KB", "ECDHOnP256AndGCM128", b)
|
||||
}
|
||||
func BenchmarkDecrypt64KBWithECDHOnP256AndGCM128(b *testing.B) {
|
||||
benchDecrypt("64KB", "ECDHOnP256AndGCM128", b)
|
||||
}
|
||||
func BenchmarkDecrypt1MBWithECDHOnP256AndGCM128(b *testing.B) {
|
||||
benchDecrypt("1MB", "ECDHOnP256AndGCM128", b)
|
||||
}
|
||||
func BenchmarkDecrypt64MBWithECDHOnP256AndGCM128(b *testing.B) {
|
||||
benchDecrypt("64MB", "ECDHOnP256AndGCM128", b)
|
||||
}
|
||||
|
||||
func BenchmarkDecrypt1BWithECDHOnP384AndGCM128(b *testing.B) {
|
||||
benchDecrypt("1B", "ECDHOnP384AndGCM128", b)
|
||||
}
|
||||
func BenchmarkDecrypt64BWithECDHOnP384AndGCM128(b *testing.B) {
|
||||
benchDecrypt("64B", "ECDHOnP384AndGCM128", b)
|
||||
}
|
||||
func BenchmarkDecrypt1KBWithECDHOnP384AndGCM128(b *testing.B) {
|
||||
benchDecrypt("1KB", "ECDHOnP384AndGCM128", b)
|
||||
}
|
||||
func BenchmarkDecrypt64KBWithECDHOnP384AndGCM128(b *testing.B) {
|
||||
benchDecrypt("64KB", "ECDHOnP384AndGCM128", b)
|
||||
}
|
||||
func BenchmarkDecrypt1MBWithECDHOnP384AndGCM128(b *testing.B) {
|
||||
benchDecrypt("1MB", "ECDHOnP384AndGCM128", b)
|
||||
}
|
||||
func BenchmarkDecrypt64MBWithECDHOnP384AndGCM128(b *testing.B) {
|
||||
benchDecrypt("64MB", "ECDHOnP384AndGCM128", b)
|
||||
}
|
||||
|
||||
func BenchmarkDecrypt1BWithECDHOnP521AndGCM128(b *testing.B) {
|
||||
benchDecrypt("1B", "ECDHOnP521AndGCM128", b)
|
||||
}
|
||||
func BenchmarkDecrypt64BWithECDHOnP521AndGCM128(b *testing.B) {
|
||||
benchDecrypt("64B", "ECDHOnP521AndGCM128", b)
|
||||
}
|
||||
func BenchmarkDecrypt1KBWithECDHOnP521AndGCM128(b *testing.B) {
|
||||
benchDecrypt("1KB", "ECDHOnP521AndGCM128", b)
|
||||
}
|
||||
func BenchmarkDecrypt64KBWithECDHOnP521AndGCM128(b *testing.B) {
|
||||
benchDecrypt("64KB", "ECDHOnP521AndGCM128", b)
|
||||
}
|
||||
func BenchmarkDecrypt1MBWithECDHOnP521AndGCM128(b *testing.B) {
|
||||
benchDecrypt("1MB", "ECDHOnP521AndGCM128", b)
|
||||
}
|
||||
func BenchmarkDecrypt64MBWithECDHOnP521AndGCM128(b *testing.B) {
|
||||
benchDecrypt("64MB", "ECDHOnP521AndGCM128", b)
|
||||
}
|
||||
|
||||
func benchDecrypt(chunkKey, primKey string, b *testing.B) {
|
||||
chunk, ok := chunks[chunkKey]
|
||||
if !ok {
|
||||
b.Fatalf("unknown chunk size %s", chunkKey)
|
||||
}
|
||||
|
||||
enc, ok := encrypters[primKey]
|
||||
if !ok {
|
||||
b.Fatalf("unknown encrypter %s", primKey)
|
||||
}
|
||||
|
||||
dec, ok := decryptionKeys[primKey]
|
||||
if !ok {
|
||||
b.Fatalf("unknown decryption key %s", primKey)
|
||||
}
|
||||
|
||||
data, err := enc.Encrypt(chunk)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
b.SetBytes(int64(len(chunk)))
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
data.Decrypt(dec)
|
||||
}
|
||||
}
|
||||
|
||||
func mustEncrypter(keyAlg KeyAlgorithm, encAlg ContentEncryption, encryptionKey interface{}) Encrypter {
|
||||
enc, err := NewEncrypter(encAlg, Recipient{Algorithm: keyAlg, Key: encryptionKey}, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return enc
|
||||
}
|
205
vendor/gopkg.in/square/go-jose.v2/doc_test.go
generated
vendored
205
vendor/gopkg.in/square/go-jose.v2/doc_test.go
generated
vendored
@@ -1,205 +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/rand"
|
||||
"crypto/rsa"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Dummy encrypter for use in examples
|
||||
var encrypter Encrypter
|
||||
|
||||
func Example_jWE() {
|
||||
// Generate a public/private key pair to use for this example. The library
|
||||
// also provides two utility functions (LoadPublicKey and LoadPrivateKey)
|
||||
// that can be used to load keys from PEM/DER-encoded data.
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Instantiate an encrypter using RSA-OAEP with AES128-GCM. An error would
|
||||
// indicate that the selected algorithm(s) are not currently supported.
|
||||
publicKey := &privateKey.PublicKey
|
||||
encrypter, err := NewEncrypter(A128GCM, Recipient{Algorithm: RSA_OAEP, Key: publicKey}, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Encrypt a sample plaintext. Calling the encrypter returns an encrypted
|
||||
// JWE object, which can then be serialized for output afterwards. An error
|
||||
// would indicate a problem in an underlying cryptographic primitive.
|
||||
var plaintext = []byte("Lorem ipsum dolor sit amet")
|
||||
object, err := encrypter.Encrypt(plaintext)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Serialize the encrypted object using the full serialization format.
|
||||
// Alternatively you can also use the compact format here by calling
|
||||
// object.CompactSerialize() instead.
|
||||
serialized := object.FullSerialize()
|
||||
|
||||
// Parse the serialized, encrypted JWE object. An error would indicate that
|
||||
// the given input did not represent a valid message.
|
||||
object, err = ParseEncrypted(serialized)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Now we can decrypt and get back our original plaintext. An error here
|
||||
// would indicate the the message failed to decrypt, e.g. because the auth
|
||||
// tag was broken or the message was tampered with.
|
||||
decrypted, err := object.Decrypt(privateKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf(string(decrypted))
|
||||
// output: Lorem ipsum dolor sit amet
|
||||
}
|
||||
|
||||
func Example_jWS() {
|
||||
// Generate a public/private key pair to use for this example. The library
|
||||
// also provides two utility functions (LoadPublicKey and LoadPrivateKey)
|
||||
// that can be used to load keys from PEM/DER-encoded data.
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Instantiate a signer using RSASSA-PSS (SHA512) with the given private key.
|
||||
signer, err := NewSigner(SigningKey{Algorithm: PS512, Key: privateKey}, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Sign a sample payload. Calling the signer returns a protected JWS object,
|
||||
// which can then be serialized for output afterwards. An error would
|
||||
// indicate a problem in an underlying cryptographic primitive.
|
||||
var payload = []byte("Lorem ipsum dolor sit amet")
|
||||
object, err := signer.Sign(payload)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Serialize the encrypted object using the full serialization format.
|
||||
// Alternatively you can also use the compact format here by calling
|
||||
// object.CompactSerialize() instead.
|
||||
serialized := object.FullSerialize()
|
||||
|
||||
// Parse the serialized, protected JWS object. An error would indicate that
|
||||
// the given input did not represent a valid message.
|
||||
object, err = ParseSigned(serialized)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Now we can verify the signature on the payload. An error here would
|
||||
// indicate the the message failed to verify, e.g. because the signature was
|
||||
// broken or the message was tampered with.
|
||||
output, err := object.Verify(&privateKey.PublicKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf(string(output))
|
||||
// output: Lorem ipsum dolor sit amet
|
||||
}
|
||||
|
||||
func ExampleNewEncrypter_publicKey() {
|
||||
var publicKey *rsa.PublicKey
|
||||
|
||||
// Instantiate an encrypter using RSA-OAEP with AES128-GCM.
|
||||
NewEncrypter(A128GCM, Recipient{Algorithm: RSA_OAEP, Key: publicKey}, nil)
|
||||
|
||||
// Instantiate an encrypter using RSA-PKCS1v1.5 with AES128-CBC+HMAC.
|
||||
NewEncrypter(A128CBC_HS256, Recipient{Algorithm: RSA1_5, Key: publicKey}, nil)
|
||||
}
|
||||
|
||||
func ExampleNewEncrypter_symmetric() {
|
||||
var sharedKey []byte
|
||||
|
||||
// Instantiate an encrypter using AES128-GCM with AES-GCM key wrap.
|
||||
NewEncrypter(A128GCM, Recipient{Algorithm: A128GCMKW, Key: sharedKey}, nil)
|
||||
|
||||
// Instantiate an encrypter using AES128-GCM directly, w/o key wrapping.
|
||||
NewEncrypter(A128GCM, Recipient{Algorithm: DIRECT, Key: sharedKey}, nil)
|
||||
}
|
||||
|
||||
func ExampleNewSigner_publicKey() {
|
||||
var rsaPrivateKey *rsa.PrivateKey
|
||||
var ecdsaPrivateKey *ecdsa.PrivateKey
|
||||
|
||||
// Instantiate a signer using RSA-PKCS#1v1.5 with SHA-256.
|
||||
NewSigner(SigningKey{Algorithm: RS256, Key: rsaPrivateKey}, nil)
|
||||
|
||||
// Instantiate a signer using ECDSA with SHA-384.
|
||||
NewSigner(SigningKey{Algorithm: ES384, Key: ecdsaPrivateKey}, nil)
|
||||
}
|
||||
|
||||
func ExampleNewSigner_symmetric() {
|
||||
var sharedKey []byte
|
||||
|
||||
// Instantiate an signer using HMAC-SHA256.
|
||||
NewSigner(SigningKey{Algorithm: HS256, Key: sharedKey}, nil)
|
||||
|
||||
// Instantiate an signer using HMAC-SHA512.
|
||||
NewSigner(SigningKey{Algorithm: HS512, Key: sharedKey}, nil)
|
||||
}
|
||||
|
||||
func ExampleNewMultiEncrypter() {
|
||||
var publicKey *rsa.PublicKey
|
||||
var sharedKey []byte
|
||||
|
||||
// Instantiate an encrypter using AES-GCM.
|
||||
NewMultiEncrypter(A128GCM, []Recipient{
|
||||
{Algorithm: A128GCMKW, Key: sharedKey},
|
||||
{Algorithm: RSA_OAEP, Key: publicKey},
|
||||
}, nil)
|
||||
}
|
||||
|
||||
func ExampleNewMultiSigner() {
|
||||
var privateKey *rsa.PrivateKey
|
||||
var sharedKey []byte
|
||||
|
||||
// Instantiate a signer for multiple recipients.
|
||||
NewMultiSigner([]SigningKey{
|
||||
{Algorithm: HS256, Key: sharedKey},
|
||||
{Algorithm: PS384, Key: privateKey},
|
||||
}, nil)
|
||||
}
|
||||
|
||||
func ExampleEncrypter_encrypt() {
|
||||
// Encrypt a plaintext in order to get an encrypted JWE object.
|
||||
var plaintext = []byte("This is a secret message")
|
||||
|
||||
encrypter.Encrypt(plaintext)
|
||||
}
|
||||
|
||||
func ExampleEncrypter_encryptWithAuthData() {
|
||||
// Encrypt a plaintext in order to get an encrypted JWE object. Also attach
|
||||
// some additional authenticated data (AAD) to the object. Note that objects
|
||||
// with attached AAD can only be represented using full serialization.
|
||||
var plaintext = []byte("This is a secret message")
|
||||
var aad = []byte("This is authenticated, but public data")
|
||||
|
||||
encrypter.EncryptWithAuthData(plaintext, aad)
|
||||
}
|
122
vendor/gopkg.in/square/go-jose.v2/encoding_test.go
generated
vendored
122
vendor/gopkg.in/square/go-jose.v2/encoding_test.go
generated
vendored
@@ -1,122 +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 (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDeflateRoundtrip(t *testing.T) {
|
||||
original := []byte("Lorem ipsum dolor sit amet")
|
||||
|
||||
compressed, err := deflate(original)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
output, err := inflate(compressed)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if bytes.Compare(output, original) != 0 {
|
||||
t.Error("Input and output do not match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidCompression(t *testing.T) {
|
||||
_, err := compress("XYZ", []byte{})
|
||||
if err == nil {
|
||||
t.Error("should not accept invalid algorithm")
|
||||
}
|
||||
|
||||
_, err = decompress("XYZ", []byte{})
|
||||
if err == nil {
|
||||
t.Error("should not accept invalid algorithm")
|
||||
}
|
||||
|
||||
_, err = decompress(DEFLATE, []byte{1, 2, 3, 4})
|
||||
if err == nil {
|
||||
t.Error("should not accept invalid data")
|
||||
}
|
||||
}
|
||||
|
||||
func TestByteBufferTrim(t *testing.T) {
|
||||
buf := newBufferFromInt(1)
|
||||
if !bytes.Equal(buf.data, []byte{1}) {
|
||||
t.Error("Byte buffer for integer '1' should contain [0x01]")
|
||||
}
|
||||
|
||||
buf = newBufferFromInt(65537)
|
||||
if !bytes.Equal(buf.data, []byte{1, 0, 1}) {
|
||||
t.Error("Byte buffer for integer '65537' should contain [0x01, 0x00, 0x01]")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFixedSizeBuffer(t *testing.T) {
|
||||
data0 := []byte{}
|
||||
data1 := []byte{1}
|
||||
data2 := []byte{1, 2}
|
||||
data3 := []byte{1, 2, 3}
|
||||
data4 := []byte{1, 2, 3, 4}
|
||||
|
||||
buf0 := newFixedSizeBuffer(data0, 4)
|
||||
buf1 := newFixedSizeBuffer(data1, 4)
|
||||
buf2 := newFixedSizeBuffer(data2, 4)
|
||||
buf3 := newFixedSizeBuffer(data3, 4)
|
||||
buf4 := newFixedSizeBuffer(data4, 4)
|
||||
|
||||
if !bytes.Equal(buf0.data, []byte{0, 0, 0, 0}) {
|
||||
t.Error("Invalid padded buffer for buf0")
|
||||
}
|
||||
if !bytes.Equal(buf1.data, []byte{0, 0, 0, 1}) {
|
||||
t.Error("Invalid padded buffer for buf1")
|
||||
}
|
||||
if !bytes.Equal(buf2.data, []byte{0, 0, 1, 2}) {
|
||||
t.Error("Invalid padded buffer for buf2")
|
||||
}
|
||||
if !bytes.Equal(buf3.data, []byte{0, 1, 2, 3}) {
|
||||
t.Error("Invalid padded buffer for buf3")
|
||||
}
|
||||
if !bytes.Equal(buf4.data, []byte{1, 2, 3, 4}) {
|
||||
t.Error("Invalid padded buffer for buf4")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSerializeJSONRejectsNil(t *testing.T) {
|
||||
defer func() {
|
||||
r := recover()
|
||||
if r == nil || !strings.Contains(r.(string), "nil pointer") {
|
||||
t.Error("serialize function should not accept nil pointer")
|
||||
}
|
||||
}()
|
||||
|
||||
mustSerializeJSON(nil)
|
||||
}
|
||||
|
||||
func TestFixedSizeBufferTooLarge(t *testing.T) {
|
||||
defer func() {
|
||||
r := recover()
|
||||
if r == nil {
|
||||
t.Error("should not be able to create fixed size buffer with oversized data")
|
||||
}
|
||||
}()
|
||||
|
||||
newFixedSizeBuffer(make([]byte, 2), 1)
|
||||
}
|
13
vendor/gopkg.in/square/go-jose.v2/json/README.md
generated
vendored
13
vendor/gopkg.in/square/go-jose.v2/json/README.md
generated
vendored
@@ -1,13 +0,0 @@
|
||||
# Safe JSON
|
||||
|
||||
This repository contains a fork of the `encoding/json` package from Go 1.6.
|
||||
|
||||
The following changes were made:
|
||||
|
||||
* Object deserialization uses case-sensitive member name matching instead of
|
||||
[case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html).
|
||||
This is to avoid differences in the interpretation of JOSE messages between
|
||||
go-jose and libraries written in other languages.
|
||||
* When deserializing a JSON object, we check for duplicate keys and reject the
|
||||
input whenever we detect a duplicate. Rather than trying to work with malformed
|
||||
data, we prefer to reject it right away.
|
223
vendor/gopkg.in/square/go-jose.v2/json/bench_test.go
generated
vendored
223
vendor/gopkg.in/square/go-jose.v2/json/bench_test.go
generated
vendored
@@ -1,223 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Large data benchmark.
|
||||
// The JSON data is a summary of agl's changes in the
|
||||
// go, webkit, and chromium open source projects.
|
||||
// We benchmark converting between the JSON form
|
||||
// and in-memory data structures.
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type codeResponse struct {
|
||||
Tree *codeNode `json:"tree"`
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
type codeNode struct {
|
||||
Name string `json:"name"`
|
||||
Kids []*codeNode `json:"kids"`
|
||||
CLWeight float64 `json:"cl_weight"`
|
||||
Touches int `json:"touches"`
|
||||
MinT int64 `json:"min_t"`
|
||||
MaxT int64 `json:"max_t"`
|
||||
MeanT int64 `json:"mean_t"`
|
||||
}
|
||||
|
||||
var codeJSON []byte
|
||||
var codeStruct codeResponse
|
||||
|
||||
func codeInit() {
|
||||
f, err := os.Open("testdata/code.json.gz")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
gz, err := gzip.NewReader(f)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
data, err := ioutil.ReadAll(gz)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
codeJSON = data
|
||||
|
||||
if err := Unmarshal(codeJSON, &codeStruct); err != nil {
|
||||
panic("unmarshal code.json: " + err.Error())
|
||||
}
|
||||
|
||||
if data, err = Marshal(&codeStruct); err != nil {
|
||||
panic("marshal code.json: " + err.Error())
|
||||
}
|
||||
|
||||
if !bytes.Equal(data, codeJSON) {
|
||||
println("different lengths", len(data), len(codeJSON))
|
||||
for i := 0; i < len(data) && i < len(codeJSON); i++ {
|
||||
if data[i] != codeJSON[i] {
|
||||
println("re-marshal: changed at byte", i)
|
||||
println("orig: ", string(codeJSON[i-10:i+10]))
|
||||
println("new: ", string(data[i-10:i+10]))
|
||||
break
|
||||
}
|
||||
}
|
||||
panic("re-marshal code.json: different result")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCodeEncoder(b *testing.B) {
|
||||
if codeJSON == nil {
|
||||
b.StopTimer()
|
||||
codeInit()
|
||||
b.StartTimer()
|
||||
}
|
||||
enc := NewEncoder(ioutil.Discard)
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err := enc.Encode(&codeStruct); err != nil {
|
||||
b.Fatal("Encode:", err)
|
||||
}
|
||||
}
|
||||
b.SetBytes(int64(len(codeJSON)))
|
||||
}
|
||||
|
||||
func BenchmarkCodeMarshal(b *testing.B) {
|
||||
if codeJSON == nil {
|
||||
b.StopTimer()
|
||||
codeInit()
|
||||
b.StartTimer()
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
if _, err := Marshal(&codeStruct); err != nil {
|
||||
b.Fatal("Marshal:", err)
|
||||
}
|
||||
}
|
||||
b.SetBytes(int64(len(codeJSON)))
|
||||
}
|
||||
|
||||
func BenchmarkCodeDecoder(b *testing.B) {
|
||||
if codeJSON == nil {
|
||||
b.StopTimer()
|
||||
codeInit()
|
||||
b.StartTimer()
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
dec := NewDecoder(&buf)
|
||||
var r codeResponse
|
||||
for i := 0; i < b.N; i++ {
|
||||
buf.Write(codeJSON)
|
||||
// hide EOF
|
||||
buf.WriteByte('\n')
|
||||
buf.WriteByte('\n')
|
||||
buf.WriteByte('\n')
|
||||
if err := dec.Decode(&r); err != nil {
|
||||
b.Fatal("Decode:", err)
|
||||
}
|
||||
}
|
||||
b.SetBytes(int64(len(codeJSON)))
|
||||
}
|
||||
|
||||
func BenchmarkDecoderStream(b *testing.B) {
|
||||
b.StopTimer()
|
||||
var buf bytes.Buffer
|
||||
dec := NewDecoder(&buf)
|
||||
buf.WriteString(`"` + strings.Repeat("x", 1000000) + `"` + "\n\n\n")
|
||||
var x interface{}
|
||||
if err := dec.Decode(&x); err != nil {
|
||||
b.Fatal("Decode:", err)
|
||||
}
|
||||
ones := strings.Repeat(" 1\n", 300000) + "\n\n\n"
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
if i%300000 == 0 {
|
||||
buf.WriteString(ones)
|
||||
}
|
||||
x = nil
|
||||
if err := dec.Decode(&x); err != nil || x != 1.0 {
|
||||
b.Fatalf("Decode: %v after %d", err, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCodeUnmarshal(b *testing.B) {
|
||||
if codeJSON == nil {
|
||||
b.StopTimer()
|
||||
codeInit()
|
||||
b.StartTimer()
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
var r codeResponse
|
||||
if err := Unmarshal(codeJSON, &r); err != nil {
|
||||
b.Fatal("Unmmarshal:", err)
|
||||
}
|
||||
}
|
||||
b.SetBytes(int64(len(codeJSON)))
|
||||
}
|
||||
|
||||
func BenchmarkCodeUnmarshalReuse(b *testing.B) {
|
||||
if codeJSON == nil {
|
||||
b.StopTimer()
|
||||
codeInit()
|
||||
b.StartTimer()
|
||||
}
|
||||
var r codeResponse
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err := Unmarshal(codeJSON, &r); err != nil {
|
||||
b.Fatal("Unmmarshal:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkUnmarshalString(b *testing.B) {
|
||||
data := []byte(`"hello, world"`)
|
||||
var s string
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err := Unmarshal(data, &s); err != nil {
|
||||
b.Fatal("Unmarshal:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkUnmarshalFloat64(b *testing.B) {
|
||||
var f float64
|
||||
data := []byte(`3.14`)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err := Unmarshal(data, &f); err != nil {
|
||||
b.Fatal("Unmarshal:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkUnmarshalInt64(b *testing.B) {
|
||||
var x int64
|
||||
data := []byte(`3`)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err := Unmarshal(data, &x); err != nil {
|
||||
b.Fatal("Unmarshal:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkIssue10335(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
var s struct{}
|
||||
j := []byte(`{"a":{ }}`)
|
||||
for n := 0; n < b.N; n++ {
|
||||
if err := Unmarshal(j, &s); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
1474
vendor/gopkg.in/square/go-jose.v2/json/decode_test.go
generated
vendored
1474
vendor/gopkg.in/square/go-jose.v2/json/decode_test.go
generated
vendored
File diff suppressed because it is too large
Load Diff
538
vendor/gopkg.in/square/go-jose.v2/json/encode_test.go
generated
vendored
538
vendor/gopkg.in/square/go-jose.v2/json/encode_test.go
generated
vendored
@@ -1,538 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
"reflect"
|
||||
"testing"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type Optionals struct {
|
||||
Sr string `json:"sr"`
|
||||
So string `json:"so,omitempty"`
|
||||
Sw string `json:"-"`
|
||||
|
||||
Ir int `json:"omitempty"` // actually named omitempty, not an option
|
||||
Io int `json:"io,omitempty"`
|
||||
|
||||
Slr []string `json:"slr,random"`
|
||||
Slo []string `json:"slo,omitempty"`
|
||||
|
||||
Mr map[string]interface{} `json:"mr"`
|
||||
Mo map[string]interface{} `json:",omitempty"`
|
||||
|
||||
Fr float64 `json:"fr"`
|
||||
Fo float64 `json:"fo,omitempty"`
|
||||
|
||||
Br bool `json:"br"`
|
||||
Bo bool `json:"bo,omitempty"`
|
||||
|
||||
Ur uint `json:"ur"`
|
||||
Uo uint `json:"uo,omitempty"`
|
||||
|
||||
Str struct{} `json:"str"`
|
||||
Sto struct{} `json:"sto,omitempty"`
|
||||
}
|
||||
|
||||
var optionalsExpected = `{
|
||||
"sr": "",
|
||||
"omitempty": 0,
|
||||
"slr": null,
|
||||
"mr": {},
|
||||
"fr": 0,
|
||||
"br": false,
|
||||
"ur": 0,
|
||||
"str": {},
|
||||
"sto": {}
|
||||
}`
|
||||
|
||||
func TestOmitEmpty(t *testing.T) {
|
||||
var o Optionals
|
||||
o.Sw = "something"
|
||||
o.Mr = map[string]interface{}{}
|
||||
o.Mo = map[string]interface{}{}
|
||||
|
||||
got, err := MarshalIndent(&o, "", " ")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := string(got); got != optionalsExpected {
|
||||
t.Errorf(" got: %s\nwant: %s\n", got, optionalsExpected)
|
||||
}
|
||||
}
|
||||
|
||||
type StringTag struct {
|
||||
BoolStr bool `json:",string"`
|
||||
IntStr int64 `json:",string"`
|
||||
StrStr string `json:",string"`
|
||||
}
|
||||
|
||||
var stringTagExpected = `{
|
||||
"BoolStr": "true",
|
||||
"IntStr": "42",
|
||||
"StrStr": "\"xzbit\""
|
||||
}`
|
||||
|
||||
func TestStringTag(t *testing.T) {
|
||||
var s StringTag
|
||||
s.BoolStr = true
|
||||
s.IntStr = 42
|
||||
s.StrStr = "xzbit"
|
||||
got, err := MarshalIndent(&s, "", " ")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got := string(got); got != stringTagExpected {
|
||||
t.Fatalf(" got: %s\nwant: %s\n", got, stringTagExpected)
|
||||
}
|
||||
|
||||
// Verify that it round-trips.
|
||||
var s2 StringTag
|
||||
err = NewDecoder(bytes.NewReader(got)).Decode(&s2)
|
||||
if err != nil {
|
||||
t.Fatalf("Decode: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(s, s2) {
|
||||
t.Fatalf("decode didn't match.\nsource: %#v\nEncoded as:\n%s\ndecode: %#v", s, string(got), s2)
|
||||
}
|
||||
}
|
||||
|
||||
// byte slices are special even if they're renamed types.
|
||||
type renamedByte byte
|
||||
type renamedByteSlice []byte
|
||||
type renamedRenamedByteSlice []renamedByte
|
||||
|
||||
func TestEncodeRenamedByteSlice(t *testing.T) {
|
||||
s := renamedByteSlice("abc")
|
||||
result, err := Marshal(s)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expect := `"YWJj"`
|
||||
if string(result) != expect {
|
||||
t.Errorf(" got %s want %s", result, expect)
|
||||
}
|
||||
r := renamedRenamedByteSlice("abc")
|
||||
result, err = Marshal(r)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(result) != expect {
|
||||
t.Errorf(" got %s want %s", result, expect)
|
||||
}
|
||||
}
|
||||
|
||||
var unsupportedValues = []interface{}{
|
||||
math.NaN(),
|
||||
math.Inf(-1),
|
||||
math.Inf(1),
|
||||
}
|
||||
|
||||
func TestUnsupportedValues(t *testing.T) {
|
||||
for _, v := range unsupportedValues {
|
||||
if _, err := Marshal(v); err != nil {
|
||||
if _, ok := err.(*UnsupportedValueError); !ok {
|
||||
t.Errorf("for %v, got %T want UnsupportedValueError", v, err)
|
||||
}
|
||||
} else {
|
||||
t.Errorf("for %v, expected error", v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ref has Marshaler and Unmarshaler methods with pointer receiver.
|
||||
type Ref int
|
||||
|
||||
func (*Ref) MarshalJSON() ([]byte, error) {
|
||||
return []byte(`"ref"`), nil
|
||||
}
|
||||
|
||||
func (r *Ref) UnmarshalJSON([]byte) error {
|
||||
*r = 12
|
||||
return nil
|
||||
}
|
||||
|
||||
// Val has Marshaler methods with value receiver.
|
||||
type Val int
|
||||
|
||||
func (Val) MarshalJSON() ([]byte, error) {
|
||||
return []byte(`"val"`), nil
|
||||
}
|
||||
|
||||
// RefText has Marshaler and Unmarshaler methods with pointer receiver.
|
||||
type RefText int
|
||||
|
||||
func (*RefText) MarshalText() ([]byte, error) {
|
||||
return []byte(`"ref"`), nil
|
||||
}
|
||||
|
||||
func (r *RefText) UnmarshalText([]byte) error {
|
||||
*r = 13
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValText has Marshaler methods with value receiver.
|
||||
type ValText int
|
||||
|
||||
func (ValText) MarshalText() ([]byte, error) {
|
||||
return []byte(`"val"`), nil
|
||||
}
|
||||
|
||||
func TestRefValMarshal(t *testing.T) {
|
||||
var s = struct {
|
||||
R0 Ref
|
||||
R1 *Ref
|
||||
R2 RefText
|
||||
R3 *RefText
|
||||
V0 Val
|
||||
V1 *Val
|
||||
V2 ValText
|
||||
V3 *ValText
|
||||
}{
|
||||
R0: 12,
|
||||
R1: new(Ref),
|
||||
R2: 14,
|
||||
R3: new(RefText),
|
||||
V0: 13,
|
||||
V1: new(Val),
|
||||
V2: 15,
|
||||
V3: new(ValText),
|
||||
}
|
||||
const want = `{"R0":"ref","R1":"ref","R2":"\"ref\"","R3":"\"ref\"","V0":"val","V1":"val","V2":"\"val\"","V3":"\"val\""}`
|
||||
b, err := Marshal(&s)
|
||||
if err != nil {
|
||||
t.Fatalf("Marshal: %v", err)
|
||||
}
|
||||
if got := string(b); got != want {
|
||||
t.Errorf("got %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// C implements Marshaler and returns unescaped JSON.
|
||||
type C int
|
||||
|
||||
func (C) MarshalJSON() ([]byte, error) {
|
||||
return []byte(`"<&>"`), nil
|
||||
}
|
||||
|
||||
// CText implements Marshaler and returns unescaped text.
|
||||
type CText int
|
||||
|
||||
func (CText) MarshalText() ([]byte, error) {
|
||||
return []byte(`"<&>"`), nil
|
||||
}
|
||||
|
||||
func TestMarshalerEscaping(t *testing.T) {
|
||||
var c C
|
||||
want := `"\u003c\u0026\u003e"`
|
||||
b, err := Marshal(c)
|
||||
if err != nil {
|
||||
t.Fatalf("Marshal(c): %v", err)
|
||||
}
|
||||
if got := string(b); got != want {
|
||||
t.Errorf("Marshal(c) = %#q, want %#q", got, want)
|
||||
}
|
||||
|
||||
var ct CText
|
||||
want = `"\"\u003c\u0026\u003e\""`
|
||||
b, err = Marshal(ct)
|
||||
if err != nil {
|
||||
t.Fatalf("Marshal(ct): %v", err)
|
||||
}
|
||||
if got := string(b); got != want {
|
||||
t.Errorf("Marshal(ct) = %#q, want %#q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
type IntType int
|
||||
|
||||
type MyStruct struct {
|
||||
IntType
|
||||
}
|
||||
|
||||
func TestAnonymousNonstruct(t *testing.T) {
|
||||
var i IntType = 11
|
||||
a := MyStruct{i}
|
||||
const want = `{"IntType":11}`
|
||||
|
||||
b, err := Marshal(a)
|
||||
if err != nil {
|
||||
t.Fatalf("Marshal: %v", err)
|
||||
}
|
||||
if got := string(b); got != want {
|
||||
t.Errorf("got %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
type BugA struct {
|
||||
S string
|
||||
}
|
||||
|
||||
type BugB struct {
|
||||
BugA
|
||||
S string
|
||||
}
|
||||
|
||||
type BugC struct {
|
||||
S string
|
||||
}
|
||||
|
||||
// Legal Go: We never use the repeated embedded field (S).
|
||||
type BugX struct {
|
||||
A int
|
||||
BugA
|
||||
BugB
|
||||
}
|
||||
|
||||
// Issue 5245.
|
||||
func TestEmbeddedBug(t *testing.T) {
|
||||
v := BugB{
|
||||
BugA{"A"},
|
||||
"B",
|
||||
}
|
||||
b, err := Marshal(v)
|
||||
if err != nil {
|
||||
t.Fatal("Marshal:", err)
|
||||
}
|
||||
want := `{"S":"B"}`
|
||||
got := string(b)
|
||||
if got != want {
|
||||
t.Fatalf("Marshal: got %s want %s", got, want)
|
||||
}
|
||||
// Now check that the duplicate field, S, does not appear.
|
||||
x := BugX{
|
||||
A: 23,
|
||||
}
|
||||
b, err = Marshal(x)
|
||||
if err != nil {
|
||||
t.Fatal("Marshal:", err)
|
||||
}
|
||||
want = `{"A":23}`
|
||||
got = string(b)
|
||||
if got != want {
|
||||
t.Fatalf("Marshal: got %s want %s", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
type BugD struct { // Same as BugA after tagging.
|
||||
XXX string `json:"S"`
|
||||
}
|
||||
|
||||
// BugD's tagged S field should dominate BugA's.
|
||||
type BugY struct {
|
||||
BugA
|
||||
BugD
|
||||
}
|
||||
|
||||
// Test that a field with a tag dominates untagged fields.
|
||||
func TestTaggedFieldDominates(t *testing.T) {
|
||||
v := BugY{
|
||||
BugA{"BugA"},
|
||||
BugD{"BugD"},
|
||||
}
|
||||
b, err := Marshal(v)
|
||||
if err != nil {
|
||||
t.Fatal("Marshal:", err)
|
||||
}
|
||||
want := `{"S":"BugD"}`
|
||||
got := string(b)
|
||||
if got != want {
|
||||
t.Fatalf("Marshal: got %s want %s", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// There are no tags here, so S should not appear.
|
||||
type BugZ struct {
|
||||
BugA
|
||||
BugC
|
||||
BugY // Contains a tagged S field through BugD; should not dominate.
|
||||
}
|
||||
|
||||
func TestDuplicatedFieldDisappears(t *testing.T) {
|
||||
v := BugZ{
|
||||
BugA{"BugA"},
|
||||
BugC{"BugC"},
|
||||
BugY{
|
||||
BugA{"nested BugA"},
|
||||
BugD{"nested BugD"},
|
||||
},
|
||||
}
|
||||
b, err := Marshal(v)
|
||||
if err != nil {
|
||||
t.Fatal("Marshal:", err)
|
||||
}
|
||||
want := `{}`
|
||||
got := string(b)
|
||||
if got != want {
|
||||
t.Fatalf("Marshal: got %s want %s", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringBytes(t *testing.T) {
|
||||
// Test that encodeState.stringBytes and encodeState.string use the same encoding.
|
||||
es := &encodeState{}
|
||||
var r []rune
|
||||
for i := '\u0000'; i <= unicode.MaxRune; i++ {
|
||||
r = append(r, i)
|
||||
}
|
||||
s := string(r) + "\xff\xff\xffhello" // some invalid UTF-8 too
|
||||
es.string(s)
|
||||
|
||||
esBytes := &encodeState{}
|
||||
esBytes.stringBytes([]byte(s))
|
||||
|
||||
enc := es.Buffer.String()
|
||||
encBytes := esBytes.Buffer.String()
|
||||
if enc != encBytes {
|
||||
i := 0
|
||||
for i < len(enc) && i < len(encBytes) && enc[i] == encBytes[i] {
|
||||
i++
|
||||
}
|
||||
enc = enc[i:]
|
||||
encBytes = encBytes[i:]
|
||||
i = 0
|
||||
for i < len(enc) && i < len(encBytes) && enc[len(enc)-i-1] == encBytes[len(encBytes)-i-1] {
|
||||
i++
|
||||
}
|
||||
enc = enc[:len(enc)-i]
|
||||
encBytes = encBytes[:len(encBytes)-i]
|
||||
|
||||
if len(enc) > 20 {
|
||||
enc = enc[:20] + "..."
|
||||
}
|
||||
if len(encBytes) > 20 {
|
||||
encBytes = encBytes[:20] + "..."
|
||||
}
|
||||
|
||||
t.Errorf("encodings differ at %#q vs %#q", enc, encBytes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssue6458(t *testing.T) {
|
||||
type Foo struct {
|
||||
M RawMessage
|
||||
}
|
||||
x := Foo{RawMessage(`"foo"`)}
|
||||
|
||||
b, err := Marshal(&x)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if want := `{"M":"foo"}`; string(b) != want {
|
||||
t.Errorf("Marshal(&x) = %#q; want %#q", b, want)
|
||||
}
|
||||
|
||||
b, err = Marshal(x)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if want := `{"M":"ImZvbyI="}`; string(b) != want {
|
||||
t.Errorf("Marshal(x) = %#q; want %#q", b, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssue10281(t *testing.T) {
|
||||
type Foo struct {
|
||||
N Number
|
||||
}
|
||||
x := Foo{Number(`invalid`)}
|
||||
|
||||
b, err := Marshal(&x)
|
||||
if err == nil {
|
||||
t.Errorf("Marshal(&x) = %#q; want error", b)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHTMLEscape(t *testing.T) {
|
||||
var b, want bytes.Buffer
|
||||
m := `{"M":"<html>foo &` + "\xe2\x80\xa8 \xe2\x80\xa9" + `</html>"}`
|
||||
want.Write([]byte(`{"M":"\u003chtml\u003efoo \u0026\u2028 \u2029\u003c/html\u003e"}`))
|
||||
HTMLEscape(&b, []byte(m))
|
||||
if !bytes.Equal(b.Bytes(), want.Bytes()) {
|
||||
t.Errorf("HTMLEscape(&b, []byte(m)) = %s; want %s", b.Bytes(), want.Bytes())
|
||||
}
|
||||
}
|
||||
|
||||
// golang.org/issue/8582
|
||||
func TestEncodePointerString(t *testing.T) {
|
||||
type stringPointer struct {
|
||||
N *int64 `json:"n,string"`
|
||||
}
|
||||
var n int64 = 42
|
||||
b, err := Marshal(stringPointer{N: &n})
|
||||
if err != nil {
|
||||
t.Fatalf("Marshal: %v", err)
|
||||
}
|
||||
if got, want := string(b), `{"n":"42"}`; got != want {
|
||||
t.Errorf("Marshal = %s, want %s", got, want)
|
||||
}
|
||||
var back stringPointer
|
||||
err = Unmarshal(b, &back)
|
||||
if err != nil {
|
||||
t.Fatalf("Unmarshal: %v", err)
|
||||
}
|
||||
if back.N == nil {
|
||||
t.Fatalf("Unmarshalled nil N field")
|
||||
}
|
||||
if *back.N != 42 {
|
||||
t.Fatalf("*N = %d; want 42", *back.N)
|
||||
}
|
||||
}
|
||||
|
||||
var encodeStringTests = []struct {
|
||||
in string
|
||||
out string
|
||||
}{
|
||||
{"\x00", `"\u0000"`},
|
||||
{"\x01", `"\u0001"`},
|
||||
{"\x02", `"\u0002"`},
|
||||
{"\x03", `"\u0003"`},
|
||||
{"\x04", `"\u0004"`},
|
||||
{"\x05", `"\u0005"`},
|
||||
{"\x06", `"\u0006"`},
|
||||
{"\x07", `"\u0007"`},
|
||||
{"\x08", `"\u0008"`},
|
||||
{"\x09", `"\t"`},
|
||||
{"\x0a", `"\n"`},
|
||||
{"\x0b", `"\u000b"`},
|
||||
{"\x0c", `"\u000c"`},
|
||||
{"\x0d", `"\r"`},
|
||||
{"\x0e", `"\u000e"`},
|
||||
{"\x0f", `"\u000f"`},
|
||||
{"\x10", `"\u0010"`},
|
||||
{"\x11", `"\u0011"`},
|
||||
{"\x12", `"\u0012"`},
|
||||
{"\x13", `"\u0013"`},
|
||||
{"\x14", `"\u0014"`},
|
||||
{"\x15", `"\u0015"`},
|
||||
{"\x16", `"\u0016"`},
|
||||
{"\x17", `"\u0017"`},
|
||||
{"\x18", `"\u0018"`},
|
||||
{"\x19", `"\u0019"`},
|
||||
{"\x1a", `"\u001a"`},
|
||||
{"\x1b", `"\u001b"`},
|
||||
{"\x1c", `"\u001c"`},
|
||||
{"\x1d", `"\u001d"`},
|
||||
{"\x1e", `"\u001e"`},
|
||||
{"\x1f", `"\u001f"`},
|
||||
}
|
||||
|
||||
func TestEncodeString(t *testing.T) {
|
||||
for _, tt := range encodeStringTests {
|
||||
b, err := Marshal(tt.in)
|
||||
if err != nil {
|
||||
t.Errorf("Marshal(%q): %v", tt.in, err)
|
||||
continue
|
||||
}
|
||||
out := string(b)
|
||||
if out != tt.out {
|
||||
t.Errorf("Marshal(%q) = %#q, want %#q", tt.in, out, tt.out)
|
||||
}
|
||||
}
|
||||
}
|
133
vendor/gopkg.in/square/go-jose.v2/json/number_test.go
generated
vendored
133
vendor/gopkg.in/square/go-jose.v2/json/number_test.go
generated
vendored
@@ -1,133 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNumberIsValid(t *testing.T) {
|
||||
// From: http://stackoverflow.com/a/13340826
|
||||
var jsonNumberRegexp = regexp.MustCompile(`^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$`)
|
||||
|
||||
validTests := []string{
|
||||
"0",
|
||||
"-0",
|
||||
"1",
|
||||
"-1",
|
||||
"0.1",
|
||||
"-0.1",
|
||||
"1234",
|
||||
"-1234",
|
||||
"12.34",
|
||||
"-12.34",
|
||||
"12E0",
|
||||
"12E1",
|
||||
"12e34",
|
||||
"12E-0",
|
||||
"12e+1",
|
||||
"12e-34",
|
||||
"-12E0",
|
||||
"-12E1",
|
||||
"-12e34",
|
||||
"-12E-0",
|
||||
"-12e+1",
|
||||
"-12e-34",
|
||||
"1.2E0",
|
||||
"1.2E1",
|
||||
"1.2e34",
|
||||
"1.2E-0",
|
||||
"1.2e+1",
|
||||
"1.2e-34",
|
||||
"-1.2E0",
|
||||
"-1.2E1",
|
||||
"-1.2e34",
|
||||
"-1.2E-0",
|
||||
"-1.2e+1",
|
||||
"-1.2e-34",
|
||||
"0E0",
|
||||
"0E1",
|
||||
"0e34",
|
||||
"0E-0",
|
||||
"0e+1",
|
||||
"0e-34",
|
||||
"-0E0",
|
||||
"-0E1",
|
||||
"-0e34",
|
||||
"-0E-0",
|
||||
"-0e+1",
|
||||
"-0e-34",
|
||||
}
|
||||
|
||||
for _, test := range validTests {
|
||||
if !isValidNumber(test) {
|
||||
t.Errorf("%s should be valid", test)
|
||||
}
|
||||
|
||||
var f float64
|
||||
if err := Unmarshal([]byte(test), &f); err != nil {
|
||||
t.Errorf("%s should be valid but Unmarshal failed: %v", test, err)
|
||||
}
|
||||
|
||||
if !jsonNumberRegexp.MatchString(test) {
|
||||
t.Errorf("%s should be valid but regexp does not match", test)
|
||||
}
|
||||
}
|
||||
|
||||
invalidTests := []string{
|
||||
"",
|
||||
"invalid",
|
||||
"1.0.1",
|
||||
"1..1",
|
||||
"-1-2",
|
||||
"012a42",
|
||||
"01.2",
|
||||
"012",
|
||||
"12E12.12",
|
||||
"1e2e3",
|
||||
"1e+-2",
|
||||
"1e--23",
|
||||
"1e",
|
||||
"e1",
|
||||
"1e+",
|
||||
"1ea",
|
||||
"1a",
|
||||
"1.a",
|
||||
"1.",
|
||||
"01",
|
||||
"1.e1",
|
||||
}
|
||||
|
||||
for _, test := range invalidTests {
|
||||
if isValidNumber(test) {
|
||||
t.Errorf("%s should be invalid", test)
|
||||
}
|
||||
|
||||
var f float64
|
||||
if err := Unmarshal([]byte(test), &f); err == nil {
|
||||
t.Errorf("%s should be invalid but unmarshal wrote %v", test, f)
|
||||
}
|
||||
|
||||
if jsonNumberRegexp.MatchString(test) {
|
||||
t.Errorf("%s should be invalid but matches regexp", test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNumberIsValid(b *testing.B) {
|
||||
s := "-61657.61667E+61673"
|
||||
for i := 0; i < b.N; i++ {
|
||||
isValidNumber(s)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNumberIsValidRegexp(b *testing.B) {
|
||||
var jsonNumberRegexp = regexp.MustCompile(`^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$`)
|
||||
s := "-61657.61667E+61673"
|
||||
for i := 0; i < b.N; i++ {
|
||||
jsonNumberRegexp.MatchString(s)
|
||||
}
|
||||
}
|
316
vendor/gopkg.in/square/go-jose.v2/json/scanner_test.go
generated
vendored
316
vendor/gopkg.in/square/go-jose.v2/json/scanner_test.go
generated
vendored
@@ -1,316 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math"
|
||||
"math/rand"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Tests of simple examples.
|
||||
|
||||
type example struct {
|
||||
compact string
|
||||
indent string
|
||||
}
|
||||
|
||||
var examples = []example{
|
||||
{`1`, `1`},
|
||||
{`{}`, `{}`},
|
||||
{`[]`, `[]`},
|
||||
{`{"":2}`, "{\n\t\"\": 2\n}"},
|
||||
{`[3]`, "[\n\t3\n]"},
|
||||
{`[1,2,3]`, "[\n\t1,\n\t2,\n\t3\n]"},
|
||||
{`{"x":1}`, "{\n\t\"x\": 1\n}"},
|
||||
{ex1, ex1i},
|
||||
}
|
||||
|
||||
var ex1 = `[true,false,null,"x",1,1.5,0,-5e+2]`
|
||||
|
||||
var ex1i = `[
|
||||
true,
|
||||
false,
|
||||
null,
|
||||
"x",
|
||||
1,
|
||||
1.5,
|
||||
0,
|
||||
-5e+2
|
||||
]`
|
||||
|
||||
func TestCompact(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
for _, tt := range examples {
|
||||
buf.Reset()
|
||||
if err := Compact(&buf, []byte(tt.compact)); err != nil {
|
||||
t.Errorf("Compact(%#q): %v", tt.compact, err)
|
||||
} else if s := buf.String(); s != tt.compact {
|
||||
t.Errorf("Compact(%#q) = %#q, want original", tt.compact, s)
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
if err := Compact(&buf, []byte(tt.indent)); err != nil {
|
||||
t.Errorf("Compact(%#q): %v", tt.indent, err)
|
||||
continue
|
||||
} else if s := buf.String(); s != tt.compact {
|
||||
t.Errorf("Compact(%#q) = %#q, want %#q", tt.indent, s, tt.compact)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompactSeparators(t *testing.T) {
|
||||
// U+2028 and U+2029 should be escaped inside strings.
|
||||
// They should not appear outside strings.
|
||||
tests := []struct {
|
||||
in, compact string
|
||||
}{
|
||||
{"{\"\u2028\": 1}", `{"\u2028":1}`},
|
||||
{"{\"\u2029\" :2}", `{"\u2029":2}`},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
var buf bytes.Buffer
|
||||
if err := Compact(&buf, []byte(tt.in)); err != nil {
|
||||
t.Errorf("Compact(%q): %v", tt.in, err)
|
||||
} else if s := buf.String(); s != tt.compact {
|
||||
t.Errorf("Compact(%q) = %q, want %q", tt.in, s, tt.compact)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndent(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
for _, tt := range examples {
|
||||
buf.Reset()
|
||||
if err := Indent(&buf, []byte(tt.indent), "", "\t"); err != nil {
|
||||
t.Errorf("Indent(%#q): %v", tt.indent, err)
|
||||
} else if s := buf.String(); s != tt.indent {
|
||||
t.Errorf("Indent(%#q) = %#q, want original", tt.indent, s)
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
if err := Indent(&buf, []byte(tt.compact), "", "\t"); err != nil {
|
||||
t.Errorf("Indent(%#q): %v", tt.compact, err)
|
||||
continue
|
||||
} else if s := buf.String(); s != tt.indent {
|
||||
t.Errorf("Indent(%#q) = %#q, want %#q", tt.compact, s, tt.indent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests of a large random structure.
|
||||
|
||||
func TestCompactBig(t *testing.T) {
|
||||
initBig()
|
||||
var buf bytes.Buffer
|
||||
if err := Compact(&buf, jsonBig); err != nil {
|
||||
t.Fatalf("Compact: %v", err)
|
||||
}
|
||||
b := buf.Bytes()
|
||||
if !bytes.Equal(b, jsonBig) {
|
||||
t.Error("Compact(jsonBig) != jsonBig")
|
||||
diff(t, b, jsonBig)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndentBig(t *testing.T) {
|
||||
initBig()
|
||||
var buf bytes.Buffer
|
||||
if err := Indent(&buf, jsonBig, "", "\t"); err != nil {
|
||||
t.Fatalf("Indent1: %v", err)
|
||||
}
|
||||
b := buf.Bytes()
|
||||
if len(b) == len(jsonBig) {
|
||||
// jsonBig is compact (no unnecessary spaces);
|
||||
// indenting should make it bigger
|
||||
t.Fatalf("Indent(jsonBig) did not get bigger")
|
||||
}
|
||||
|
||||
// should be idempotent
|
||||
var buf1 bytes.Buffer
|
||||
if err := Indent(&buf1, b, "", "\t"); err != nil {
|
||||
t.Fatalf("Indent2: %v", err)
|
||||
}
|
||||
b1 := buf1.Bytes()
|
||||
if !bytes.Equal(b1, b) {
|
||||
t.Error("Indent(Indent(jsonBig)) != Indent(jsonBig)")
|
||||
diff(t, b1, b)
|
||||
return
|
||||
}
|
||||
|
||||
// should get back to original
|
||||
buf1.Reset()
|
||||
if err := Compact(&buf1, b); err != nil {
|
||||
t.Fatalf("Compact: %v", err)
|
||||
}
|
||||
b1 = buf1.Bytes()
|
||||
if !bytes.Equal(b1, jsonBig) {
|
||||
t.Error("Compact(Indent(jsonBig)) != jsonBig")
|
||||
diff(t, b1, jsonBig)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
type indentErrorTest struct {
|
||||
in string
|
||||
err error
|
||||
}
|
||||
|
||||
var indentErrorTests = []indentErrorTest{
|
||||
{`{"X": "foo", "Y"}`, &SyntaxError{"invalid character '}' after object key", 17}},
|
||||
{`{"X": "foo" "Y": "bar"}`, &SyntaxError{"invalid character '\"' after object key:value pair", 13}},
|
||||
}
|
||||
|
||||
func TestIndentErrors(t *testing.T) {
|
||||
for i, tt := range indentErrorTests {
|
||||
slice := make([]uint8, 0)
|
||||
buf := bytes.NewBuffer(slice)
|
||||
if err := Indent(buf, []uint8(tt.in), "", ""); err != nil {
|
||||
if !reflect.DeepEqual(err, tt.err) {
|
||||
t.Errorf("#%d: Indent: %#v", i, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNextValueBig(t *testing.T) {
|
||||
initBig()
|
||||
var scan scanner
|
||||
item, rest, err := nextValue(jsonBig, &scan)
|
||||
if err != nil {
|
||||
t.Fatalf("nextValue: %s", err)
|
||||
}
|
||||
if len(item) != len(jsonBig) || &item[0] != &jsonBig[0] {
|
||||
t.Errorf("invalid item: %d %d", len(item), len(jsonBig))
|
||||
}
|
||||
if len(rest) != 0 {
|
||||
t.Errorf("invalid rest: %d", len(rest))
|
||||
}
|
||||
|
||||
item, rest, err = nextValue(append(jsonBig, "HELLO WORLD"...), &scan)
|
||||
if err != nil {
|
||||
t.Fatalf("nextValue extra: %s", err)
|
||||
}
|
||||
if len(item) != len(jsonBig) {
|
||||
t.Errorf("invalid item: %d %d", len(item), len(jsonBig))
|
||||
}
|
||||
if string(rest) != "HELLO WORLD" {
|
||||
t.Errorf("invalid rest: %d", len(rest))
|
||||
}
|
||||
}
|
||||
|
||||
var benchScan scanner
|
||||
|
||||
func BenchmarkSkipValue(b *testing.B) {
|
||||
initBig()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
nextValue(jsonBig, &benchScan)
|
||||
}
|
||||
b.SetBytes(int64(len(jsonBig)))
|
||||
}
|
||||
|
||||
func diff(t *testing.T, a, b []byte) {
|
||||
for i := 0; ; i++ {
|
||||
if i >= len(a) || i >= len(b) || a[i] != b[i] {
|
||||
j := i - 10
|
||||
if j < 0 {
|
||||
j = 0
|
||||
}
|
||||
t.Errorf("diverge at %d: «%s» vs «%s»", i, trim(a[j:]), trim(b[j:]))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func trim(b []byte) []byte {
|
||||
if len(b) > 20 {
|
||||
return b[0:20]
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// Generate a random JSON object.
|
||||
|
||||
var jsonBig []byte
|
||||
|
||||
func initBig() {
|
||||
n := 10000
|
||||
if testing.Short() {
|
||||
n = 100
|
||||
}
|
||||
b, err := Marshal(genValue(n))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
jsonBig = b
|
||||
}
|
||||
|
||||
func genValue(n int) interface{} {
|
||||
if n > 1 {
|
||||
switch rand.Intn(2) {
|
||||
case 0:
|
||||
return genArray(n)
|
||||
case 1:
|
||||
return genMap(n)
|
||||
}
|
||||
}
|
||||
switch rand.Intn(3) {
|
||||
case 0:
|
||||
return rand.Intn(2) == 0
|
||||
case 1:
|
||||
return rand.NormFloat64()
|
||||
case 2:
|
||||
return genString(30)
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func genString(stddev float64) string {
|
||||
n := int(math.Abs(rand.NormFloat64()*stddev + stddev/2))
|
||||
c := make([]rune, n)
|
||||
for i := range c {
|
||||
f := math.Abs(rand.NormFloat64()*64 + 32)
|
||||
if f > 0x10ffff {
|
||||
f = 0x10ffff
|
||||
}
|
||||
c[i] = rune(f)
|
||||
}
|
||||
return string(c)
|
||||
}
|
||||
|
||||
func genArray(n int) []interface{} {
|
||||
f := int(math.Abs(rand.NormFloat64()) * math.Min(10, float64(n/2)))
|
||||
if f > n {
|
||||
f = n
|
||||
}
|
||||
if f < 1 {
|
||||
f = 1
|
||||
}
|
||||
x := make([]interface{}, f)
|
||||
for i := range x {
|
||||
x[i] = genValue(((i+1)*n)/f - (i*n)/f)
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
func genMap(n int) map[string]interface{} {
|
||||
f := int(math.Abs(rand.NormFloat64()) * math.Min(10, float64(n/2)))
|
||||
if f > n {
|
||||
f = n
|
||||
}
|
||||
if n > 0 && f == 0 {
|
||||
f = 1
|
||||
}
|
||||
x := make(map[string]interface{})
|
||||
for i := 0; i < f; i++ {
|
||||
x[genString(10)] = genValue(((i+1)*n)/f - (i*n)/f)
|
||||
}
|
||||
return x
|
||||
}
|
354
vendor/gopkg.in/square/go-jose.v2/json/stream_test.go
generated
vendored
354
vendor/gopkg.in/square/go-jose.v2/json/stream_test.go
generated
vendored
@@ -1,354 +0,0 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Test values for the stream test.
|
||||
// One of each JSON kind.
|
||||
var streamTest = []interface{}{
|
||||
0.1,
|
||||
"hello",
|
||||
nil,
|
||||
true,
|
||||
false,
|
||||
[]interface{}{"a", "b", "c"},
|
||||
map[string]interface{}{"K": "Kelvin", "ß": "long s"},
|
||||
3.14, // another value to make sure something can follow map
|
||||
}
|
||||
|
||||
var streamEncoded = `0.1
|
||||
"hello"
|
||||
null
|
||||
true
|
||||
false
|
||||
["a","b","c"]
|
||||
{"ß":"long s","K":"Kelvin"}
|
||||
3.14
|
||||
`
|
||||
|
||||
func TestEncoder(t *testing.T) {
|
||||
for i := 0; i <= len(streamTest); i++ {
|
||||
var buf bytes.Buffer
|
||||
enc := NewEncoder(&buf)
|
||||
for j, v := range streamTest[0:i] {
|
||||
if err := enc.Encode(v); err != nil {
|
||||
t.Fatalf("encode #%d: %v", j, err)
|
||||
}
|
||||
}
|
||||
if have, want := buf.String(), nlines(streamEncoded, i); have != want {
|
||||
t.Errorf("encoding %d items: mismatch", i)
|
||||
diff(t, []byte(have), []byte(want))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecoder(t *testing.T) {
|
||||
for i := 0; i <= len(streamTest); i++ {
|
||||
// Use stream without newlines as input,
|
||||
// just to stress the decoder even more.
|
||||
// Our test input does not include back-to-back numbers.
|
||||
// Otherwise stripping the newlines would
|
||||
// merge two adjacent JSON values.
|
||||
var buf bytes.Buffer
|
||||
for _, c := range nlines(streamEncoded, i) {
|
||||
if c != '\n' {
|
||||
buf.WriteRune(c)
|
||||
}
|
||||
}
|
||||
out := make([]interface{}, i)
|
||||
dec := NewDecoder(&buf)
|
||||
for j := range out {
|
||||
if err := dec.Decode(&out[j]); err != nil {
|
||||
t.Fatalf("decode #%d/%d: %v", j, i, err)
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(out, streamTest[0:i]) {
|
||||
t.Errorf("decoding %d items: mismatch", i)
|
||||
for j := range out {
|
||||
if !reflect.DeepEqual(out[j], streamTest[j]) {
|
||||
t.Errorf("#%d: have %v want %v", j, out[j], streamTest[j])
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecoderBuffered(t *testing.T) {
|
||||
r := strings.NewReader(`{"Name": "Gopher"} extra `)
|
||||
var m struct {
|
||||
Name string
|
||||
}
|
||||
d := NewDecoder(r)
|
||||
err := d.Decode(&m)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if m.Name != "Gopher" {
|
||||
t.Errorf("Name = %q; want Gopher", m.Name)
|
||||
}
|
||||
rest, err := ioutil.ReadAll(d.Buffered())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if g, w := string(rest), " extra "; g != w {
|
||||
t.Errorf("Remaining = %q; want %q", g, w)
|
||||
}
|
||||
}
|
||||
|
||||
func nlines(s string, n int) string {
|
||||
if n <= 0 {
|
||||
return ""
|
||||
}
|
||||
for i, c := range s {
|
||||
if c == '\n' {
|
||||
if n--; n == 0 {
|
||||
return s[0 : i+1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func TestRawMessage(t *testing.T) {
|
||||
// TODO(rsc): Should not need the * in *RawMessage
|
||||
var data struct {
|
||||
X float64
|
||||
Id *RawMessage
|
||||
Y float32
|
||||
}
|
||||
const raw = `["\u0056",null]`
|
||||
const msg = `{"X":0.1,"Id":["\u0056",null],"Y":0.2}`
|
||||
err := Unmarshal([]byte(msg), &data)
|
||||
if err != nil {
|
||||
t.Fatalf("Unmarshal: %v", err)
|
||||
}
|
||||
if string([]byte(*data.Id)) != raw {
|
||||
t.Fatalf("Raw mismatch: have %#q want %#q", []byte(*data.Id), raw)
|
||||
}
|
||||
b, err := Marshal(&data)
|
||||
if err != nil {
|
||||
t.Fatalf("Marshal: %v", err)
|
||||
}
|
||||
if string(b) != msg {
|
||||
t.Fatalf("Marshal: have %#q want %#q", b, msg)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNullRawMessage(t *testing.T) {
|
||||
// TODO(rsc): Should not need the * in *RawMessage
|
||||
var data struct {
|
||||
X float64
|
||||
Id *RawMessage
|
||||
Y float32
|
||||
}
|
||||
data.Id = new(RawMessage)
|
||||
const msg = `{"X":0.1,"Id":null,"Y":0.2}`
|
||||
err := Unmarshal([]byte(msg), &data)
|
||||
if err != nil {
|
||||
t.Fatalf("Unmarshal: %v", err)
|
||||
}
|
||||
if data.Id != nil {
|
||||
t.Fatalf("Raw mismatch: have non-nil, want nil")
|
||||
}
|
||||
b, err := Marshal(&data)
|
||||
if err != nil {
|
||||
t.Fatalf("Marshal: %v", err)
|
||||
}
|
||||
if string(b) != msg {
|
||||
t.Fatalf("Marshal: have %#q want %#q", b, msg)
|
||||
}
|
||||
}
|
||||
|
||||
var blockingTests = []string{
|
||||
`{"x": 1}`,
|
||||
`[1, 2, 3]`,
|
||||
}
|
||||
|
||||
func TestBlocking(t *testing.T) {
|
||||
for _, enc := range blockingTests {
|
||||
r, w := net.Pipe()
|
||||
go w.Write([]byte(enc))
|
||||
var val interface{}
|
||||
|
||||
// If Decode reads beyond what w.Write writes above,
|
||||
// it will block, and the test will deadlock.
|
||||
if err := NewDecoder(r).Decode(&val); err != nil {
|
||||
t.Errorf("decoding %s: %v", enc, err)
|
||||
}
|
||||
r.Close()
|
||||
w.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEncoderEncode(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
type T struct {
|
||||
X, Y string
|
||||
}
|
||||
v := &T{"foo", "bar"}
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err := NewEncoder(ioutil.Discard).Encode(v); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type tokenStreamCase struct {
|
||||
json string
|
||||
expTokens []interface{}
|
||||
}
|
||||
|
||||
type decodeThis struct {
|
||||
v interface{}
|
||||
}
|
||||
|
||||
var tokenStreamCases []tokenStreamCase = []tokenStreamCase{
|
||||
// streaming token cases
|
||||
{json: `10`, expTokens: []interface{}{float64(10)}},
|
||||
{json: ` [10] `, expTokens: []interface{}{
|
||||
Delim('['), float64(10), Delim(']')}},
|
||||
{json: ` [false,10,"b"] `, expTokens: []interface{}{
|
||||
Delim('['), false, float64(10), "b", Delim(']')}},
|
||||
{json: `{ "a": 1 }`, expTokens: []interface{}{
|
||||
Delim('{'), "a", float64(1), Delim('}')}},
|
||||
{json: `{"a": 1, "b":"3"}`, expTokens: []interface{}{
|
||||
Delim('{'), "a", float64(1), "b", "3", Delim('}')}},
|
||||
{json: ` [{"a": 1},{"a": 2}] `, expTokens: []interface{}{
|
||||
Delim('['),
|
||||
Delim('{'), "a", float64(1), Delim('}'),
|
||||
Delim('{'), "a", float64(2), Delim('}'),
|
||||
Delim(']')}},
|
||||
{json: `{"obj": {"a": 1}}`, expTokens: []interface{}{
|
||||
Delim('{'), "obj", Delim('{'), "a", float64(1), Delim('}'),
|
||||
Delim('}')}},
|
||||
{json: `{"obj": [{"a": 1}]}`, expTokens: []interface{}{
|
||||
Delim('{'), "obj", Delim('['),
|
||||
Delim('{'), "a", float64(1), Delim('}'),
|
||||
Delim(']'), Delim('}')}},
|
||||
|
||||
// streaming tokens with intermittent Decode()
|
||||
{json: `{ "a": 1 }`, expTokens: []interface{}{
|
||||
Delim('{'), "a",
|
||||
decodeThis{float64(1)},
|
||||
Delim('}')}},
|
||||
{json: ` [ { "a" : 1 } ] `, expTokens: []interface{}{
|
||||
Delim('['),
|
||||
decodeThis{map[string]interface{}{"a": float64(1)}},
|
||||
Delim(']')}},
|
||||
{json: ` [{"a": 1},{"a": 2}] `, expTokens: []interface{}{
|
||||
Delim('['),
|
||||
decodeThis{map[string]interface{}{"a": float64(1)}},
|
||||
decodeThis{map[string]interface{}{"a": float64(2)}},
|
||||
Delim(']')}},
|
||||
{json: `{ "obj" : [ { "a" : 1 } ] }`, expTokens: []interface{}{
|
||||
Delim('{'), "obj", Delim('['),
|
||||
decodeThis{map[string]interface{}{"a": float64(1)}},
|
||||
Delim(']'), Delim('}')}},
|
||||
|
||||
{json: `{"obj": {"a": 1}}`, expTokens: []interface{}{
|
||||
Delim('{'), "obj",
|
||||
decodeThis{map[string]interface{}{"a": float64(1)}},
|
||||
Delim('}')}},
|
||||
{json: `{"obj": [{"a": 1}]}`, expTokens: []interface{}{
|
||||
Delim('{'), "obj",
|
||||
decodeThis{[]interface{}{
|
||||
map[string]interface{}{"a": float64(1)},
|
||||
}},
|
||||
Delim('}')}},
|
||||
{json: ` [{"a": 1} {"a": 2}] `, expTokens: []interface{}{
|
||||
Delim('['),
|
||||
decodeThis{map[string]interface{}{"a": float64(1)}},
|
||||
decodeThis{&SyntaxError{"expected comma after array element", 0}},
|
||||
}},
|
||||
{json: `{ "a" 1 }`, expTokens: []interface{}{
|
||||
Delim('{'), "a",
|
||||
decodeThis{&SyntaxError{"expected colon after object key", 0}},
|
||||
}},
|
||||
}
|
||||
|
||||
func TestDecodeInStream(t *testing.T) {
|
||||
|
||||
for ci, tcase := range tokenStreamCases {
|
||||
|
||||
dec := NewDecoder(strings.NewReader(tcase.json))
|
||||
for i, etk := range tcase.expTokens {
|
||||
|
||||
var tk interface{}
|
||||
var err error
|
||||
|
||||
if dt, ok := etk.(decodeThis); ok {
|
||||
etk = dt.v
|
||||
err = dec.Decode(&tk)
|
||||
} else {
|
||||
tk, err = dec.Token()
|
||||
}
|
||||
if experr, ok := etk.(error); ok {
|
||||
if err == nil || err.Error() != experr.Error() {
|
||||
t.Errorf("case %v: Expected error %v in %q, but was %v", ci, experr, tcase.json, err)
|
||||
}
|
||||
break
|
||||
} else if err == io.EOF {
|
||||
t.Errorf("case %v: Unexpected EOF in %q", ci, tcase.json)
|
||||
break
|
||||
} else if err != nil {
|
||||
t.Errorf("case %v: Unexpected error '%v' in %q", ci, err, tcase.json)
|
||||
break
|
||||
}
|
||||
if !reflect.DeepEqual(tk, etk) {
|
||||
t.Errorf(`case %v: %q @ %v expected %T(%v) was %T(%v)`, ci, tcase.json, i, etk, etk, tk, tk)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Test from golang.org/issue/11893
|
||||
func TestHTTPDecoding(t *testing.T) {
|
||||
const raw = `{ "foo": "bar" }`
|
||||
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte(raw))
|
||||
}))
|
||||
defer ts.Close()
|
||||
res, err := http.Get(ts.URL)
|
||||
if err != nil {
|
||||
log.Fatalf("GET failed: %v", err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
foo := struct {
|
||||
Foo string `json:"foo"`
|
||||
}{}
|
||||
|
||||
d := NewDecoder(res.Body)
|
||||
err = d.Decode(&foo)
|
||||
if err != nil {
|
||||
t.Fatalf("Decode: %v", err)
|
||||
}
|
||||
if foo.Foo != "bar" {
|
||||
t.Errorf("decoded %q; want \"bar\"", foo.Foo)
|
||||
}
|
||||
|
||||
// make sure we get the EOF the second time
|
||||
err = d.Decode(&foo)
|
||||
if err != io.EOF {
|
||||
t.Errorf("err = %v; want io.EOF", err)
|
||||
}
|
||||
}
|
115
vendor/gopkg.in/square/go-jose.v2/json/tagkey_test.go
generated
vendored
115
vendor/gopkg.in/square/go-jose.v2/json/tagkey_test.go
generated
vendored
@@ -1,115 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type basicLatin2xTag struct {
|
||||
V string `json:"$%-/"`
|
||||
}
|
||||
|
||||
type basicLatin3xTag struct {
|
||||
V string `json:"0123456789"`
|
||||
}
|
||||
|
||||
type basicLatin4xTag struct {
|
||||
V string `json:"ABCDEFGHIJKLMO"`
|
||||
}
|
||||
|
||||
type basicLatin5xTag struct {
|
||||
V string `json:"PQRSTUVWXYZ_"`
|
||||
}
|
||||
|
||||
type basicLatin6xTag struct {
|
||||
V string `json:"abcdefghijklmno"`
|
||||
}
|
||||
|
||||
type basicLatin7xTag struct {
|
||||
V string `json:"pqrstuvwxyz"`
|
||||
}
|
||||
|
||||
type miscPlaneTag struct {
|
||||
V string `json:"色は匂へど"`
|
||||
}
|
||||
|
||||
type percentSlashTag struct {
|
||||
V string `json:"text/html%"` // https://golang.org/issue/2718
|
||||
}
|
||||
|
||||
type punctuationTag struct {
|
||||
V string `json:"!#$%&()*+-./:<=>?@[]^_{|}~"` // https://golang.org/issue/3546
|
||||
}
|
||||
|
||||
type emptyTag struct {
|
||||
W string
|
||||
}
|
||||
|
||||
type misnamedTag struct {
|
||||
X string `jsom:"Misnamed"`
|
||||
}
|
||||
|
||||
type badFormatTag struct {
|
||||
Y string `:"BadFormat"`
|
||||
}
|
||||
|
||||
type badCodeTag struct {
|
||||
Z string `json:" !\"#&'()*+,."`
|
||||
}
|
||||
|
||||
type spaceTag struct {
|
||||
Q string `json:"With space"`
|
||||
}
|
||||
|
||||
type unicodeTag struct {
|
||||
W string `json:"Ελλάδα"`
|
||||
}
|
||||
|
||||
var structTagObjectKeyTests = []struct {
|
||||
raw interface{}
|
||||
value string
|
||||
key string
|
||||
}{
|
||||
{basicLatin2xTag{"2x"}, "2x", "$%-/"},
|
||||
{basicLatin3xTag{"3x"}, "3x", "0123456789"},
|
||||
{basicLatin4xTag{"4x"}, "4x", "ABCDEFGHIJKLMO"},
|
||||
{basicLatin5xTag{"5x"}, "5x", "PQRSTUVWXYZ_"},
|
||||
{basicLatin6xTag{"6x"}, "6x", "abcdefghijklmno"},
|
||||
{basicLatin7xTag{"7x"}, "7x", "pqrstuvwxyz"},
|
||||
{miscPlaneTag{"いろはにほへと"}, "いろはにほへと", "色は匂へど"},
|
||||
{emptyTag{"Pour Moi"}, "Pour Moi", "W"},
|
||||
{misnamedTag{"Animal Kingdom"}, "Animal Kingdom", "X"},
|
||||
{badFormatTag{"Orfevre"}, "Orfevre", "Y"},
|
||||
{badCodeTag{"Reliable Man"}, "Reliable Man", "Z"},
|
||||
{percentSlashTag{"brut"}, "brut", "text/html%"},
|
||||
{punctuationTag{"Union Rags"}, "Union Rags", "!#$%&()*+-./:<=>?@[]^_{|}~"},
|
||||
{spaceTag{"Perreddu"}, "Perreddu", "With space"},
|
||||
{unicodeTag{"Loukanikos"}, "Loukanikos", "Ελλάδα"},
|
||||
}
|
||||
|
||||
func TestStructTagObjectKey(t *testing.T) {
|
||||
for _, tt := range structTagObjectKeyTests {
|
||||
b, err := Marshal(tt.raw)
|
||||
if err != nil {
|
||||
t.Fatalf("Marshal(%#q) failed: %v", tt.raw, err)
|
||||
}
|
||||
var f interface{}
|
||||
err = Unmarshal(b, &f)
|
||||
if err != nil {
|
||||
t.Fatalf("Unmarshal(%#q) failed: %v", b, err)
|
||||
}
|
||||
for i, v := range f.(map[string]interface{}) {
|
||||
switch i {
|
||||
case tt.key:
|
||||
if s, ok := v.(string); !ok || s != tt.value {
|
||||
t.Fatalf("Unexpected value: %#q, want %v", s, tt.value)
|
||||
}
|
||||
default:
|
||||
t.Fatalf("Unexpected key: %#q, from %#q", i, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
28
vendor/gopkg.in/square/go-jose.v2/json/tags_test.go
generated
vendored
28
vendor/gopkg.in/square/go-jose.v2/json/tags_test.go
generated
vendored
@@ -1,28 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTagParsing(t *testing.T) {
|
||||
name, opts := parseTag("field,foobar,foo")
|
||||
if name != "field" {
|
||||
t.Fatalf("name = %q, want field", name)
|
||||
}
|
||||
for _, tt := range []struct {
|
||||
opt string
|
||||
want bool
|
||||
}{
|
||||
{"foobar", true},
|
||||
{"foo", true},
|
||||
{"bar", false},
|
||||
} {
|
||||
if opts.Contains(tt.opt) != tt.want {
|
||||
t.Errorf("Contains(%q) = %v", tt.opt, !tt.want)
|
||||
}
|
||||
}
|
||||
}
|
538
vendor/gopkg.in/square/go-jose.v2/jwe_test.go
generated
vendored
538
vendor/gopkg.in/square/go-jose.v2/jwe_test.go
generated
vendored
@@ -1,538 +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 (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCompactParseJWE(t *testing.T) {
|
||||
// Should parse
|
||||
msg := "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.dGVzdA.dGVzdA.dGVzdA"
|
||||
_, err := ParseEncrypted(msg)
|
||||
if err != nil {
|
||||
t.Error("Unable to parse valid message:", err)
|
||||
}
|
||||
|
||||
// Messages that should fail to parse
|
||||
failures := []string{
|
||||
// Too many parts
|
||||
"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.dGVzdA.dGVzdA.dGVzdA.dGVzdA",
|
||||
// Not enough parts
|
||||
"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.dGVzdA.dGVzdA",
|
||||
// Invalid encrypted key
|
||||
"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.//////.dGVzdA.dGVzdA.dGVzdA",
|
||||
// Invalid IV
|
||||
"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.//////.dGVzdA.dGVzdA",
|
||||
// Invalid ciphertext
|
||||
"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.dGVzdA.//////.dGVzdA",
|
||||
// Invalid tag
|
||||
"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.dGVzdA.dGVzdA.dGVzdA.//////",
|
||||
// Invalid header
|
||||
"W10.dGVzdA.dGVzdA.dGVzdA.dGVzdA",
|
||||
// Invalid header
|
||||
"######.dGVzdA.dGVzdA.dGVzdA.dGVzdA",
|
||||
// Missing alc/enc params
|
||||
"e30.dGVzdA.dGVzdA.dGVzdA.dGVzdA",
|
||||
}
|
||||
|
||||
for _, msg := range failures {
|
||||
_, err = ParseEncrypted(msg)
|
||||
if err == nil {
|
||||
t.Error("Able to parse invalid message", msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFullParseJWE(t *testing.T) {
|
||||
// Messages that should succeed to parse
|
||||
successes := []string{
|
||||
// Flattened serialization, single recipient
|
||||
"{\"protected\":\"eyJhbGciOiJYWVoiLCJlbmMiOiJYWVoifQo\",\"encrypted_key\":\"QUJD\",\"iv\":\"QUJD\",\"ciphertext\":\"QUJD\",\"tag\":\"QUJD\"}",
|
||||
// Unflattened serialization, single recipient
|
||||
"{\"protected\":\"\",\"unprotected\":{\"enc\":\"XYZ\"},\"recipients\":[{\"header\":{\"alg\":\"XYZ\"},\"encrypted_key\":\"QUJD\"}],\"iv\":\"QUJD\",\"ciphertext\":\"QUJD\",\"tag\":\"QUJD\"}",
|
||||
}
|
||||
|
||||
for i := range successes {
|
||||
_, err := ParseEncrypted(successes[i])
|
||||
if err != nil {
|
||||
t.Error("Unble to parse valid message", err, successes[i])
|
||||
}
|
||||
}
|
||||
|
||||
// Messages that should fail to parse
|
||||
failures := []string{
|
||||
// Empty
|
||||
"{}",
|
||||
// Invalid JSON
|
||||
"{XX",
|
||||
// Invalid protected header
|
||||
"{\"protected\":\"###\"}",
|
||||
// Invalid protected header
|
||||
"{\"protected\":\"e1gK\"}",
|
||||
// Invalid encrypted key
|
||||
"{\"protected\":\"e30\",\"encrypted_key\":\"###\"}",
|
||||
// Invalid IV
|
||||
"{\"protected\":\"e30\",\"encrypted_key\":\"QUJD\",\"iv\":\"###\"}",
|
||||
// Invalid ciphertext
|
||||
"{\"protected\":\"e30\",\"encrypted_key\":\"QUJD\",\"iv\":\"QUJD\",\"ciphertext\":\"###\"}",
|
||||
// Invalid tag
|
||||
"{\"protected\":\"e30\",\"encrypted_key\":\"QUJD\",\"iv\":\"QUJD\",\"ciphertext\":\"QUJD\",\"tag\":\"###\"}",
|
||||
// Invalid AAD
|
||||
"{\"protected\":\"e30\",\"encrypted_key\":\"QUJD\",\"iv\":\"QUJD\",\"ciphertext\":\"QUJD\",\"tag\":\"QUJD\",\"aad\":\"###\"}",
|
||||
// Missing alg/enc headers
|
||||
"{\"protected\":\"e30\",\"encrypted_key\":\"QUJD\",\"iv\":\"QUJD\",\"ciphertext\":\"QUJD\",\"tag\":\"QUJD\"}",
|
||||
// Missing enc header
|
||||
"{\"protected\":\"eyJhbGciOiJYWVoifQ\",\"encrypted_key\":\"QUJD\",\"iv\":\"QUJD\",\"ciphertext\":\"QUJD\",\"tag\":\"QUJD\"}",
|
||||
// Missing alg header
|
||||
"{\"protected\":\"eyJlbmMiOiJYWVoifQ\",\"encrypted_key\":\"QUJD\",\"iv\":\"QUJD\",\"ciphertext\":\"QUJD\",\"tag\":\"QUJD\"}",
|
||||
// Unflattened serialization, single recipient, invalid encrypted_key
|
||||
"{\"protected\":\"\",\"recipients\":[{\"header\":{\"alg\":\"XYZ\", \"enc\":\"XYZ\"},\"encrypted_key\":\"###\"}],\"iv\":\"QUJD\",\"ciphertext\":\"QUJD\",\"tag\":\"QUJD\"}",
|
||||
// Unflattened serialization, single recipient, missing alg
|
||||
"{\"protected\":\"eyJhbGciOiJYWVoifQ\",\"recipients\":[{\"encrypted_key\":\"QUJD\"}],\"iv\":\"QUJD\",\"ciphertext\":\"QUJD\",\"tag\":\"QUJD\"}",
|
||||
}
|
||||
|
||||
for i := range failures {
|
||||
_, err := ParseEncrypted(failures[i])
|
||||
if err == nil {
|
||||
t.Error("Able to parse invalid message", err, failures[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMissingInvalidHeaders(t *testing.T) {
|
||||
obj := &JSONWebEncryption{
|
||||
protected: &rawHeader{Enc: A128GCM},
|
||||
unprotected: &rawHeader{},
|
||||
recipients: []recipientInfo{
|
||||
{},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := obj.Decrypt(nil)
|
||||
if err != ErrUnsupportedKeyType {
|
||||
t.Error("should detect invalid key")
|
||||
}
|
||||
|
||||
obj.unprotected.Crit = []string{"1", "2"}
|
||||
|
||||
_, err = obj.Decrypt(nil)
|
||||
if err == nil {
|
||||
t.Error("should reject message with crit header")
|
||||
}
|
||||
|
||||
obj.unprotected.Crit = nil
|
||||
obj.protected = &rawHeader{Alg: string(RSA1_5)}
|
||||
|
||||
_, err = obj.Decrypt(rsaTestKey)
|
||||
if err == nil || err == ErrCryptoFailure {
|
||||
t.Error("should detect missing enc header")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRejectUnprotectedJWENonce(t *testing.T) {
|
||||
// No need to test compact, since that's always protected
|
||||
|
||||
// Flattened JSON
|
||||
input := `{
|
||||
"header": {
|
||||
"alg": "XYZ", "enc": "XYZ",
|
||||
"nonce": "should-cause-an-error"
|
||||
},
|
||||
"encrypted_key": "does-not-matter",
|
||||
"aad": "does-not-matter",
|
||||
"iv": "does-not-matter",
|
||||
"ciphertext": "does-not-matter",
|
||||
"tag": "does-not-matter"
|
||||
}`
|
||||
_, err := ParseEncrypted(input)
|
||||
if err == nil {
|
||||
t.Error("JWE with an unprotected nonce parsed as valid.")
|
||||
} else if err.Error() != "square/go-jose: Nonce parameter included in unprotected header" {
|
||||
t.Errorf("Improper error for unprotected nonce: %v", err)
|
||||
}
|
||||
|
||||
input = `{
|
||||
"unprotected": {
|
||||
"alg": "XYZ", "enc": "XYZ",
|
||||
"nonce": "should-cause-an-error"
|
||||
},
|
||||
"encrypted_key": "does-not-matter",
|
||||
"aad": "does-not-matter",
|
||||
"iv": "does-not-matter",
|
||||
"ciphertext": "does-not-matter",
|
||||
"tag": "does-not-matter"
|
||||
}`
|
||||
_, err = ParseEncrypted(input)
|
||||
if err == nil {
|
||||
t.Error("JWE with an unprotected nonce parsed as valid.")
|
||||
} else if err.Error() != "square/go-jose: Nonce parameter included in unprotected header" {
|
||||
t.Errorf("Improper error for unprotected nonce: %v", err)
|
||||
}
|
||||
|
||||
// Full JSON
|
||||
input = `{
|
||||
"header": { "alg": "XYZ", "enc": "XYZ" },
|
||||
"aad": "does-not-matter",
|
||||
"iv": "does-not-matter",
|
||||
"ciphertext": "does-not-matter",
|
||||
"tag": "does-not-matter",
|
||||
"recipients": [{
|
||||
"header": { "nonce": "should-cause-an-error" },
|
||||
"encrypted_key": "does-not-matter"
|
||||
}]
|
||||
}`
|
||||
_, err = ParseEncrypted(input)
|
||||
if err == nil {
|
||||
t.Error("JWS with an unprotected nonce parsed as valid.")
|
||||
} else if err.Error() != "square/go-jose: Nonce parameter included in unprotected header" {
|
||||
t.Errorf("Improper error for unprotected nonce: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompactSerialize(t *testing.T) {
|
||||
// Compact serialization must fail if we have unprotected headers
|
||||
obj := &JSONWebEncryption{
|
||||
unprotected: &rawHeader{Alg: "XYZ"},
|
||||
}
|
||||
|
||||
_, err := obj.CompactSerialize()
|
||||
if err == nil {
|
||||
t.Error("Object with unprotected headers can't be compact serialized")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVectorsJWE(t *testing.T) {
|
||||
plaintext := []byte("The true sign of intelligence is not knowledge but imagination.")
|
||||
|
||||
publicKey := &rsa.PublicKey{
|
||||
N: fromBase64Int(`
|
||||
oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW
|
||||
cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S
|
||||
psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a
|
||||
sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS
|
||||
tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj
|
||||
YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw`),
|
||||
E: 65537,
|
||||
}
|
||||
|
||||
expectedCompact := stripWhitespace(`
|
||||
eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.ROQCfge4JPm_
|
||||
yACxv1C1NSXmwNbL6kvmCuyxBRGpW57DvlwByjyjsb6g8m7wtLMqKEyhFCn
|
||||
tV7sjippEePIlKln6BvVnz5ZLXHNYQgmubuNq8MC0KTwcaGJ_C0z_T8j4PZ
|
||||
a1nfpbhSe-ePYaALrf_nIsSRKu7cWsrwOSlaRPecRnYeDd_ytAxEQWYEKFi
|
||||
Pszc70fP9geZOB_09y9jq0vaOF0jGmpIAmgk71lCcUpSdrhNokTKo5y8MH8
|
||||
3NcbIvmuZ51cjXQj1f0_AwM9RW3oCh2Hu0z0C5l4BujZVsDuGgMsGZsjUhS
|
||||
RZsAQSXHCAmlJ2NlnN60U7y4SPJhKv5tKYw.48V1_ALb6US04U3b.5eym8T
|
||||
W_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6jiS
|
||||
diwkIr3ajwQzaBtQD_A.XFBoMYUZodetZdvTiFvSkQ`)
|
||||
|
||||
expectedFull := stripWhitespace(`
|
||||
{ "protected":"eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ",
|
||||
"encrypted_key":
|
||||
"ROQCfge4JPm_yACxv1C1NSXmwNbL6kvmCuyxBRGpW57DvlwByjyjsb
|
||||
6g8m7wtLMqKEyhFCntV7sjippEePIlKln6BvVnz5ZLXHNYQgmubuNq
|
||||
8MC0KTwcaGJ_C0z_T8j4PZa1nfpbhSe-ePYaALrf_nIsSRKu7cWsrw
|
||||
OSlaRPecRnYeDd_ytAxEQWYEKFiPszc70fP9geZOB_09y9jq0vaOF0
|
||||
jGmpIAmgk71lCcUpSdrhNokTKo5y8MH83NcbIvmuZ51cjXQj1f0_Aw
|
||||
M9RW3oCh2Hu0z0C5l4BujZVsDuGgMsGZsjUhSRZsAQSXHCAmlJ2Nln
|
||||
N60U7y4SPJhKv5tKYw",
|
||||
"iv": "48V1_ALb6US04U3b",
|
||||
"ciphertext":
|
||||
"5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFS
|
||||
hS8iB7j6jiSdiwkIr3ajwQzaBtQD_A",
|
||||
"tag":"XFBoMYUZodetZdvTiFvSkQ" }`)
|
||||
|
||||
// Mock random reader
|
||||
randReader = bytes.NewReader([]byte{
|
||||
// Encryption key
|
||||
177, 161, 244, 128, 84, 143, 225, 115, 63, 180, 3, 255, 107, 154,
|
||||
212, 246, 138, 7, 110, 91, 112, 46, 34, 105, 47, 130, 203, 46, 122,
|
||||
234, 64, 252,
|
||||
// Randomness for RSA-OAEP
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Initialization vector
|
||||
227, 197, 117, 252, 2, 219, 233, 68, 180, 225, 77, 219})
|
||||
defer resetRandReader()
|
||||
|
||||
// Encrypt with a dummy key
|
||||
encrypter, err := NewEncrypter(A256GCM, Recipient{Algorithm: RSA_OAEP, Key: publicKey}, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
object, err := encrypter.Encrypt(plaintext)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
serialized, err := object.CompactSerialize()
|
||||
if serialized != expectedCompact {
|
||||
t.Error("Compact serialization is not what we expected", serialized, expectedCompact)
|
||||
}
|
||||
|
||||
serialized = object.FullSerialize()
|
||||
if serialized != expectedFull {
|
||||
t.Error("Full serialization is not what we expected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVectorsJWECorrupt(t *testing.T) {
|
||||
priv := &rsa.PrivateKey{
|
||||
PublicKey: rsa.PublicKey{
|
||||
N: fromHexInt(`
|
||||
a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8
|
||||
ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0c
|
||||
bc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bd
|
||||
bf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93
|
||||
ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb`),
|
||||
E: 65537,
|
||||
},
|
||||
D: fromHexInt(`
|
||||
53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf1195
|
||||
17ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d
|
||||
4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d6
|
||||
5a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb
|
||||
04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1`),
|
||||
Primes: []*big.Int{
|
||||
fromHexInt(`
|
||||
d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262
|
||||
864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c
|
||||
2f26a471dcad212eac7ca39d`),
|
||||
fromHexInt(`
|
||||
cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb3
|
||||
3d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af
|
||||
72bfe9a030e860b0288b5d77`),
|
||||
},
|
||||
}
|
||||
|
||||
corruptCiphertext := stripWhitespace(`
|
||||
eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.NFl09dehy
|
||||
IR2Oh5iSsvEa82Ps7DLjRHeo0RnuTuSR45OsaIP6U8yu7vLlWaZKSZMy
|
||||
B2qRBSujf-5XIRoNhtyIyjk81eJRXGa_Bxaor1XBCMyyhGchW2H2P71f
|
||||
PhDO6ufSC7kV4bNqgHR-4ziS7KXwzN83_5kogXqxUpymUoJDNc.tk-GT
|
||||
W_VVhiTIKFF.D_BE6ImZUl9F.52a-zFnRb3YQwIC7UrhVyQ`)
|
||||
|
||||
corruptAuthtag := stripWhitespace(`
|
||||
eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.NFl09dehy
|
||||
IR2Oh5iSsvEa82Ps7DLjRHeo0RnuTuSR45OsaIP6U8yu7vLlWaZKSZMy
|
||||
B2qRBSujf-5XIRoNhtyIyjk81eJRXGa_Bxaor1XBCMyyhGchW2H2P71f
|
||||
PhDO6ufSC7kV4bNqgHR-4ziS7KNwzN83_5kogXqxUpymUoJDNc.tk-GT
|
||||
W_VVhiTIKFF.D_BE6ImZUl9F.52a-zFnRb3YQwiC7UrhVyQ`)
|
||||
|
||||
msg, _ := ParseEncrypted(corruptCiphertext)
|
||||
_, err := msg.Decrypt(priv)
|
||||
if err != ErrCryptoFailure {
|
||||
t.Error("should detect corrupt ciphertext")
|
||||
}
|
||||
|
||||
msg, _ = ParseEncrypted(corruptAuthtag)
|
||||
_, err = msg.Decrypt(priv)
|
||||
if err != ErrCryptoFailure {
|
||||
t.Error("should detect corrupt auth tag")
|
||||
}
|
||||
}
|
||||
|
||||
// Test vectors generated with nimbus-jose-jwt
|
||||
func TestSampleNimbusJWEMessagesRSA(t *testing.T) {
|
||||
rsaPrivateKey, err := x509.ParsePKCS8PrivateKey(fromBase64Bytes(`
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCNRCEmf5PlbXKuT4uwnb
|
||||
wGKvFrtpi+bDYxOZxxqxdVkZM/bYATAnD1fg9pNvLMKeF+MWJ9kPIMmDgOh9RdnRdLvQGb
|
||||
BzhLmxwhhcua2QYiHEZizXmiaXvNP12bzEBhebdX7ObW8izMVW0p0lqHPNzkK3K75B0Sxo
|
||||
FMVKkZ7KtBHgepBT5yPhPPcNe5lXQeTne5bo3I60DRcN9jTBgMJOXdq0I9o4y6ZmoXdNTm
|
||||
0EyLzn9/EYiHqBxtKFh791EHR7wYgyi/t+nOKr4sO74NbEByP0mHDil+mPvZSzFW4l7fPx
|
||||
OclRZvpRIKIub2TroZA9s2WsshGf79eqqXYbBB9NNRAgMBAAECggEAIExbZ/nzTplfhwsY
|
||||
3SCzRJW87OuqsJ79JPQPGM4NX7sQ94eJqM7+FKLl0yCFErjgnYGdCyiArvB+oJPdsimgke
|
||||
h83X0hGeg03lVA3/6OsG3WifCAxulnLN44AM8KST8S9D9t5+cm5vEBLHazzAfWWTS13s+g
|
||||
9hH8rf8NSqgZ36EutjKlvLdHx1mWcKX7SREFVHT8FWPAbdhTLEHUjoWHrfSektnczaSHnt
|
||||
q8fFJy6Ld13QkF1ZJRUhtA24XrD+qLTc+M36IuedjeZaLHFB+KyhYR3YvXEtrbCug7dCRd
|
||||
uG6uTlDCSaSy7xHeTPolWtWo9F202jal54otxiAJFGUHgQKBgQDRAT0s6YQZUfwE0wluXV
|
||||
k0JdhDdCo8sC1aMmKlRKWUkBAqrDl7BI3MF56VOr4ybr90buuscshFf9TtrtBOjHSGcfDI
|
||||
tSKfhhkW5ewQKB0YqyHzoD6UKT0/XAshFY3esc3uCxuJ/6vOiXV0og9o7eFvr51O0TfDFh
|
||||
mcTvW4wirKlQKBgQCtB7UAu8I9Nn8czkd6oXLDRyTWYviuiqFmxR+PM9klgZtsumkeSxO1
|
||||
lkfFoj9+G8nFaqYEBA9sPeNtJVTSROCvj/iQtoqpV2NiI/wWeVszpBwsswx2mlks4LJa8a
|
||||
Yz9xrsfNoroKYVppefc/MCoSx4M+99RSm3FSpLGZQHAUGyzQKBgQDMQmq4JuuMF1y2lk0E
|
||||
SESyuz21BqV0tDVOjilsHT+5hmXWXoS6nkO6L2czrrpM7YE82F6JJZBmo7zEIXHBInGLJ3
|
||||
XLoYLZ5qNEhqYDUEDHaBCBWZ1vDTKnZlwWFEuXVavNNZvPbUhKTHq25t8qjDki/r09Vykp
|
||||
BsM2yNBKpbBOVQKBgCJyUVd3CaFUExQyAMrqD0XPCQdhJq7gzGcAQVsp8EXmOoH3zmuIeM
|
||||
ECzQEMXuWFNLMHm0tbX5Kl83vMHcnKioyI9ewhWxOBYTitf0ceG8j5F97SOl32NmCXzwoJ
|
||||
55Oa0xJXfLuIvOe8hZzp4WwZmBfKBxiCR166aPQQgIawelrVAoGAEJsHomfCI4epxH4oMw
|
||||
qYJMCGy95zloB+2+c86BZCOJAGwnfzbtc2eutWZw61/9sSO8sQCfzA8oX+5HwAgnFVzwW4
|
||||
lNMZohppYcpwN9EyjkPaCXuALC7p5rF2o63wY7JLvnjS2aYZliknh2yW6X6fSB0PK0Cpvd
|
||||
lAIyRw6Kud0zI=`))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
rsaSampleMessages := []string{
|
||||
"eyJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiUlNBMV81In0.EW0KOhHeoAxTBnLjYhh2T6HjwI-srNs6RpcSdZvE-GJ5iww3EYWBCmeGGj1UVz6OcBfwW3wllZ6GPOHU-hxVQH5KYpVOjkmrFIYU6-8BHhxBP_PjSJEBCZzjOgsCm9Th4-zmlO7UWTdK_UtwE7nk4X-kkmEy-aZBCShA8nFe2MVvqD5F7nvEWNFBOHh8ae_juo-kvycoIzvxLV9g1B0Zn8K9FAlu8YF1KiL5NFekn76f3jvAwlExuRbFPUx4gJN6CeBDK_D57ABsY2aBVDSiQceuYZxvCIAajqSS6dMT382FNJzAiQhToOpo_1w5FnnBjzJLLEKDk_I-Eo2YCWxxsQ.5mCMuxJqLRuPXGAr.Ghe4INeBhP3MDWGvyNko7qanKdZIzKjfeiU.ja3UlVWJXKNFJ-rZsJWycw",
|
||||
"eyJlbmMiOiJBMTkyR0NNIiwiYWxnIjoiUlNBMV81In0.JsJeYoP0St1bRYNUaAmA34DAA27usE7RNuC2grGikBRmh1xrwUOpnEIXXpwr7fjVmNi52zzWkNHC8JkkRTrLcCh2VXvnOnarpH8DCr9qM6440bSrahzbxIvDds8z8q0wT1W4kjVnq1mGwGxg8RQNBWTV6Sp2FLQkZyjzt_aXsgYzr3zEmLZxB-d41lBS81Mguk_hdFJIg_WO4ao54lozvxkCn_uMiIZ8eLb8qHy0h-N21tiHGCaiC2vV8KXomwoqbJ0SXrEH4r9_R2J844H80TBZdbvNBd8whvoQNHvOX659LNs9EQ9xxvHU2kqGZekXBu7sDXXTjctMkMITobGSzw.1v5govaDvanP3LGp.llwYNBDrD7MwVLaFHesljlratfmndWs4XPQ.ZGT1zk9_yIKi2GzW6CuAyA",
|
||||
"eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBMV81In0.fBv3fA3TMS3ML8vlsCuvwdsKvB0ym8R30jJrlOiqkWKk7WVUkjDInFzr1zw3Owla6c5BqOJNoACXt4IWbkLbkoWV3tweXlWwpafuaWPkjLOUH_K31rS2fCX5x-MTj8_hScquVQXpbz3vk2EfulRmGXZc_8JU2NqQCAsYy3a28houqP3rDe5jEAvZS2SOFvJkKW--f5S-z39t1D7fNz1N8Btd9SmXWQzjbul5YNxI9ctqxhJpkKYpxOLlvrzdA6YdJjOlDx3n6S-HnSZGM6kQd_xKtAf8l1EGwhQmhbXhMhjVxMvGwE5BX7PAb8Ccde5bzOCJx-PVbVetuLb169ZYqQ._jiZbOPRR82FEWMZ.88j68LI-K2KT6FMBEdlz6amG5nvaJU8a-90.EnEbUTJsWNqJYKzfO0x4Yw",
|
||||
"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiUlNBMV81In0.bN6FN0qmGxhkESiVukrCaDVG3woL0xE-0bHN_Mu0WZXTQWbzzT-7jOvaN1xhGK8nzi8qpCSRgE5onONNB9i8OnJm3MMIxF7bUUEAXO9SUAFn2v--wNc4drPc5OjIu0RiJrDVDkkGjNrBDIuBaEQcke7A0v91PH58dXE7o4TLPzC8UJmRtXWhUSwjXVF3-UmYRMht2rjHJlvRbtm6Tu2LMBIopRL0zj6tlPP4Dm7I7sz9OEB3VahYAhpXnFR7D_f8RjLSXQmBvB1FiI5l_vMz2NFt2hYUmQF3EJMLIEdHvvPp3iHDGiXC1obJrDID_CCf3qs9UY7DMYL622KLvP2NIg.qb72oxECzxd_aNuHVR0aNg.Gwet9Ms8hB8rKEb0h4RGdFNRq97Qs2LQaJM0HWrCqoI.03ljVThOFvgXzMmQJ79VjQ",
|
||||
"eyJlbmMiOiJBMTkyQ0JDLUhTMzg0IiwiYWxnIjoiUlNBMV81In0.ZbEOP6rqdiIP4g7Nl1PL5gwhgDwv9RinyiUQxZXPOmD7kwEZrZ093dJnhqI9kEd3QGFlHDpB7HgNz53d27z2zmEj1-27v6miizq6tH4sN2MoeZLwSyk16O1_n3bVdDmROawsTYYFJfHsuLwyVJxPd37duIYnbUCFO9J8lLIv-2VI50KJ1t47YfE4P-Wt9jVzxP2CVUQaJwTlcwfiDLJTagYmfyrDjf525WlQFlgfJGqsJKp8BX9gmKvAo-1iCBAM8VpEjS0u0_hW9VSye36yh8BthVV-VJkhJ-0tMpto3bbBmj7M25Xf4gbTrrVU7Nz6wb18YZuhHZWmj2Y2nHV6Jg.AjnS44blTrIIfFlqVw0_Mg.muCRgaEXNKKpW8rMfW7jf7Zpn3VwSYDz-JTRg16jZxY.qjc9OGlMaaWKDWQSIwVpR4K556Pp6SF9",
|
||||
"eyJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiYWxnIjoiUlNBMV81In0.c7_F1lMlRHQQE3WbKmtHBYTosdZrG9hPfs-F9gNQYet61zKG8NXVkSy0Zf2UFHt0vhcO8hP2qrqOFsy7vmRj20xnGHQ2EE29HH6hwX5bx1Jj3uE5WT9Gvh0OewpvF9VubbwWTIObBpdEG7XdJsMAQlIxtXUmQYAtLTWcy2ZJipyJtVlWQLaPuE8BKfZH-XAsp2CpQNiRPI8Ftza3EAspiyRfVQbjKt7nF8nuZ2sESjt7Y50q4CSiiCuGT28T3diMN0_rWrH-I-xx7OQvJlrQaNGglGtu3jKUcrJDcvxW2e1OxriaTeuQ848ayuRvGUNeSv6WoVYmkiK1x_gNwUAAbw.7XtSqHJA7kjt6JrfxJMwiA.Yvi4qukAbdT-k-Fd2s4G8xzL4VFxaFC0ZIzgFDAI6n0.JSWPJ-HjOE3SK9Lm0yHclmjS7Z1ahtQga9FHGCWVRcc",
|
||||
"eyJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ.SYVxJbCnJ_tcR13LJpaqHQj-nGNkMxre4A1FmnUdxnvzeJwuvyrLiUdRsZR1IkP4fqLtDON2mumx39QeJQf0WIObPBYlIxycRLkwxDHRVlyTmPvdZHAxN26jPrk09wa5SgK1UF1W1VSQIPm-Tek8jNAmarF1Yxzxl-t54wZFlQiHP4TuaczugO5f-J4nlWenfla2mU1snDgdUMlEZGOAQ_gTEtwSgd1MqXmK_7LZBkoDqqoCujMZhziafJPXPDaUUqBLW3hHkkDA7GpVec3XcTtNUWQJqOpMyQhqo1KQMc8jg3fuirILp-hjvvNVtBnCRBvbrKUCPzu2_yH3HM_agA.2VsdijtonAxShNIW.QzzB3P9CxYP3foNKN0Ma1Z9tMwijAlkWo08.ZdQkIPDY_M-hxqi5fD4NGw",
|
||||
"eyJlbmMiOiJBMTkyR0NNIiwiYWxnIjoiUlNBLU9BRVAifQ.Z2oTJXXib1u-S38Vn3DRKE3JnhnwgUa92UhsefzY2Wpdn0dmxMfYt9iRoJGFfSAcA97MOfjyvXVRCKWXGrG5AZCMAXEqU8SNQwKPRjlcqojcVzQyMucXI0ikLC4mUgeRlfKTwsBicq6JZZylzRoLGGSNJQbni3_BLsf7H3Qor0BYg0FPCLG9Z2OVvrFzvjTLmZtV6gFlVrMHBxJub_aUet9gAkxiu1Wx_Kx46TlLX2tkumXIpTGlzX6pef6jLeZ5EIg_K-Uz4tkWgWQIEkLD7qmTyk5pAGmzukHa_08jIh5-U-Sd8XGZdx4J1pVPJ5CPg0qDJGZ_cfgkgpWbP_wB6A.4qgKfokK1EwYxz20._Md82bv_KH2Vru0Ue2Eb6oAqHP2xBBP5jF8.WFRojvQpD5VmZlOr_dN0rQ",
|
||||
"eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ.JzCUgJcBJmBgByp4PBAABUfhezPvndxBIVzaoZ96DAS0HPni0OjMbsOGsz6JwNsiTr1gSn_S6R1WpZM8GJc9R2z0EKKVP67TR62ZSG0MEWyLpHmG_4ug0fAp1HWWMa9bT4ApSaOLgwlpVAb_-BPZZgIu6c8cREuMon6UBHDqW1euTBbzk8zix3-FTZ6p5b_3soDL1wXfRiRBEsxxUGMnpryx1OFb8Od0JdyGF0GgfLt6OoaujDJpo-XtLRawu1Xlg6GqRs0NQwSHZ5jXgQ6-zgCufXonAmYTiIyBXY2no9XmECTexjwrS_05nA7H-UyIZEBOCp3Yhz2zxrt5j_0pvQ.SJR-ghhaUKP4zXtZ.muiuzLfZA0y0BDNsroGTw2r2-l73SLf9lK8.XFMH1oHr1G6ByP3dWSUUPA",
|
||||
"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiUlNBLU9BRVAifQ.U946MVfIm4Dpk_86HrnIA-QXyiUu0LZ67PL93CMLmEtJemMNDqmRd9fXyenCIhAC7jPIV1aaqW7gS194xyrrnUpBoJBdbegiPqOfquy493Iq_GQ8OXnFxFibPNQ6rU0l8BwIfh28ei_VIF2jqN6bhxFURCVW7fG6n6zkCCuEyc7IcxWafSHjH2FNttREuVj-jS-4LYDZsFzSKbpqoYF6mHt8H3btNEZDTSmy_6v0fV1foNtUKNfWopCp-iE4hNh4EzJfDuU8eXLhDb03aoOockrUiUCh-E0tQx9su4rOv-mDEOHHAQK7swm5etxoa7__9PC3Hg97_p4GM9gC9ykNgw.pnXwvoSPi0kMQP54of-HGg.RPJt1CMWs1nyotx1fOIfZ8760mYQ69HlyDp3XmdVsZ8.Yxw2iPVWaBROFE_FGbvodA",
|
||||
"eyJlbmMiOiJBMTkyQ0JDLUhTMzg0IiwiYWxnIjoiUlNBLU9BRVAifQ.eKEOIJUJpXmO_ghH_nGCJmoEspqKyiy3D5l0P8lKutlo8AuYHPQlgOsaFYnDkypyUVWd9zi-JaQuCeo7dzoBiS1L71nAZo-SUoN0anQBkVuyuRjr-deJMhPPfq1H86tTk-4rKzPr1Ivd2RGXMtWsrUpNGk81r1v8DdMntLE7UxZQqT34ONuZg1IXnD_U6di7k07unI29zuU1ySeUr6w1YPw5aUDErMlpZcEJWrgOEYWaS2nuC8sWGlPGYEjqkACMFGn-y40UoS_JatNZO6gHK3SKZnXD7vN5NAaMo_mFNbh50e1t_zO8DaUdLtXPOBLcx_ULoteNd9H8HyDGWqwAPw.0xmtzJfeVMoIT1Cp68QrXA.841l1aA4c3uvSYfw6l180gn5JZQjL53WQ5fr8ejtvoI.lojzeWql_3gDq-AoaIbl_aGQRH_54w_f",
|
||||
"eyJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiYWxnIjoiUlNBLU9BRVAifQ.D0QkvIXR1TL7dIHWuPNMybmmD8UPyQd1bRKjRDNbA2HmKGpamCtcJmpNB_EetNFe-LDmhe44BYI_XN2wIBbYURKgDK_WG9BH0LQw_nCVqQ-sKqjtj3yQeytXhLHYTDmiF0TO-uW-RFR7GbPAdARBfuf4zj82r_wDD9sD5WSCGx89iPfozDOYQ_OLwdL2WD99VvDyfwS3ZhxA-9IMSYv5pwqPkxj4C0JdjCqrN0YNrZn_1ORgjtsVmcWXsmusObTozUGA7n5GeVepfZdU1vrMulAwdRYqOYtlqKaOpFowe9xFN3ncBG7wb4f9pmzbS_Dgt-1_Ii_4SEB9GQ4NiuBZ0w.N4AZeCxMGUv52A0UVJsaZw.5eHOGbZdtahnp3l_PDY-YojYib4ft4SRmdsQ2kggrTs.WsmGH8ZDv4ctBFs7qsQvw2obe4dVToRcAQaZ3PYL34E",
|
||||
"eyJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.fDTxO_ZzZ3Jdrdw-bxvg7u-xWB2q1tp3kI5zH6JfhLUm4h6rt9qDA_wZlRym8-GzEtkUjkTtQGs6HgQx_qlyy8ylCakY5GHsNhCG4m0UNhRiNfcasAs03JSXfON9-tfTJimWD9n4k5OHHhvcrsCW1G3jYeLsK9WHCGRIhNz5ULbo8HBrCTbmZ6bOEQ9mqhdssLpdV24HDpebotf3bgPJqoaTfWU6Uy7tLmPiNuuNRLQ-iTpLyNMTVvGqqZhpcV3lAEN5l77QabI5xLJYucvYjrXQhAEZ7YXO8oRYhGkdG2XXIRcwr87rBeRH-47HAyhZgF_PBPBhhrJNS9UNMqdfBw.FvU4_s7Md6vxnXWd.fw29Q4_gHt4f026DPPV-CNebQ8plJ6IVLX8._apBZrw7WsT8HOmxgCrTwA",
|
||||
"eyJlbmMiOiJBMTkyR0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.bYuorK-rHMbO4c2CRWtvyOEaM1EN-o-wLRZ0wFWRX9mCXQ-iTNarZn7ksYM1XnGmZ4u3CSowX1Hpca9Rg72_VJCmKapqCT7r3YfasN4_oeLwuSKI_gT-uVOznod97tn3Gf_EDv0y1V4H0k9BEIFGbajAcG1znTD_ODY3j2KZJxisfrsBoslc6N-HI0kKZMC2hSGuHOcOf8HN1sTE-BLqZCtoj-zxQECJK8Wh14Ih4jzzdmmiu_qmSR780K6su-4PRt3j8uY7oCiLBfwpCsCmhJgp8rKd91zoedZmamfvX38mJIfE52j4fG6HmIYw9Ov814fk9OffV6tzixjcg54Q2g.yeVJz4aSh2s-GUr9.TBzzWP5llEiDdugpP2SmPf2U4MEGG9EoPWk.g25UoWpsBaOd45J__FX7mA",
|
||||
"eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.h9tFtmh762JuffBxlSQbJujCyI4Zs9yc3IOb1yR8g65W4ZHosIvzVGHWbShj4EY9MNrz-RbKtHfqQGGzDeo3Xb4-HcQ2ZDHyWoUg7VfA8JafJ5zIKL1npz8eUExOVMLsAaRfHg8qNfczodg3egoSmX5Q-nrx4DeidDSXYZaZjV0C72stLTPcuQ7XPV7z1tvERAkqpvcsRmJn_PiRNxIbAgoyHMJ4Gijuzt1bWZwezlxYmw0TEuwCTVC2fl9NJTZyxOntS1Lcm-WQGlPkVYeVgYTOQXLlp7tF9t-aAvYpth2oWGT6Y-hbPrjx_19WaKD0XyWCR46V32DlXEVDP3Xl2A.NUgfnzQyEaJjzt9r.k2To43B2YVWMeR-w3n4Pr2b5wYq2o87giHk.X8_QYCg0IGnn1pJqe8p_KA",
|
||||
"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.EDq6cNP6Yp1sds5HZ4CkXYp7bs9plIYVZScKvuyxUy0H1VyBC_YWg0HvndPNb-vwh1LA6KMxRazlOwJ9iPR9YzHnYmGgPM3Je_ZzBfiPlRfq6hQBpGnNaypBI1XZ2tyFBhulsVLqyJe2SmM2Ud00kasOdMYgcN8FNFzq7IOE7E0FUQkIwLdUL1nrzepiYDp-5bGkxWRcL02cYfdqdm00G4m0GkUxAmdxa3oPNxZlt2NeBI_UVWQSgJE-DJVJQkDcyA0id27TV2RCDnmujYauNT_wYlyb0bFDx3pYzzNXfAXd4wHZxt75QaLZ5APJ0EVfiXJ0qki6kT-GRVmOimUbQA.vTULZL7LvS0WD8kR8ZUtLg.mb2f0StEmmkuuvsyz8UplMvF58FtZzlu8eEwzvPUvN0.hbhveEN40V-pgG2hSVgyKg",
|
||||
"eyJlbmMiOiJBMTkyQ0JDLUhTMzg0IiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.DuYk92p7u-YIN-JKn-XThmlVcnhU9x5TieQ2uhsLQVNlo0iWC9JJPP6bT6aI6u_1BIS3yE8_tSGGL7eM-zyEk6LuTqSWFRaZcZC06d0MnS9eYZcw1T2D17fL-ki-NtCaTahJD7jE2s0HevRVW49YtL-_V8whnO_EyVjvXIAQlPYqhH_o-0Nzcpng9ggdAnuF2rY1_6iRPYFJ3BLQvG1oWhyJ9s6SBttlOa0i6mmFCVLHx6sRpdGAB3lbCL3wfmHq4tpIv77gfoYUNP0SNff-zNmBXF_wp3dCntLZFTjbfMpGyHlruF_uoaLqwdjYpUGNUFVUoeSiMnSbMKm9NxiDgQ.6Mdgcqz7bMU1UeoAwFC8pg.W36QWOlBaJezakUX5FMZzbAgeAu_R14AYKZCQmuhguw.5OeyIJ03olxmJft8uBmjuOFQPWNZMYLI",
|
||||
"eyJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.ECulJArWFsPL2FlpCN0W8E7IseSjJg1cZqE3wz5jk9gvwgNForAUEv5KYZqhNI-p5IxkGV0f8K6Y2X8pWzbLwiPIjZe8_dVqHYJoINxqCSgWLBhz0V36qL9Nc_xARTBk4-ZteIu75NoXVeos9gNvFnkOCj4tm-jGo8z8EFO9XfODgjhiR4xv8VqUtvrkjo9GQConaga5zpV-J4JQlXbdqbDjnuwacnJAxYpFyuemqcgqsl6BnFX3tovGkmSUPqcvF1A6tiHqr-TEmcgVqo5C3xswknRBKTQRM00iAmJ92WlVdkoOCx6E6O7cVHFawZ14BLzWzm66Crb4tv0ucYvk_Q.mxolwUaoj5S5kHCfph0w8g.nFpgYdnYg3blHCCEi2XXQGkkKQBXs2OkZaH11m3PRvk.k8BAVT4EcyrUFVIKr-KOSPbF89xyL0Vri2rFTu2iIWM",
|
||||
}
|
||||
|
||||
for _, msg := range rsaSampleMessages {
|
||||
obj, err := ParseEncrypted(msg)
|
||||
if err != nil {
|
||||
t.Error("unable to parse message", msg, err)
|
||||
continue
|
||||
}
|
||||
plaintext, err := obj.Decrypt(rsaPrivateKey)
|
||||
if err != nil {
|
||||
t.Error("unable to decrypt message", msg, err)
|
||||
continue
|
||||
}
|
||||
if string(plaintext) != "Lorem ipsum dolor sit amet" {
|
||||
t.Error("plaintext is not what we expected for msg", msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test vectors generated with nimbus-jose-jwt
|
||||
func TestSampleNimbusJWEMessagesAESKW(t *testing.T) {
|
||||
aesTestKeys := [][]byte{
|
||||
fromHexBytes("DF1FA4F36FFA7FC42C81D4B3C033928D"),
|
||||
fromHexBytes("DF1FA4F36FFA7FC42C81D4B3C033928D95EC9CDC2D82233C"),
|
||||
fromHexBytes("DF1FA4F36FFA7FC42C81D4B3C033928D95EC9CDC2D82233C333C35BA29044E90"),
|
||||
}
|
||||
|
||||
aesSampleMessages := [][]string{
|
||||
{
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTI4R0NNIiwidGFnIjoib2ZMd2Q5NGloVWFRckJ0T1pQUDdjUSIsImFsZyI6IkExMjhHQ01LVyIsIml2IjoiV2Z3TnN5cjEwWUFjY2p2diJ9.9x3RxdqIS6P9xjh93Eu1bQ.6fs3_fSGt2jull_5.YDlzr6sWACkFg_GU5MEc-ZEWxNLwI_JMKe_jFA.f-pq-V7rlSSg_q2e1gDygw",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTkyR0NNIiwidGFnIjoic2RneXB1ckFjTEFzTmZJU0lkZUNpUSIsImFsZyI6IkExMjhHQ01LVyIsIml2IjoieVFMR0dCdDJFZ0c1THdyViJ9.arslKo4aKlh6f4s0z1_-U-8JbmhAoZHN.Xw2Q-GX98YXwuc4i.halTEWMWAYZbv-qOD52G6bte4x6sxlh1_VpGEA.Z1spn016v58cW6Q2o0Qxag",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMjU2R0NNIiwidGFnIjoicTNzejF5VUlhbVBDYXJfZ05kSVJqQSIsImFsZyI6IkExMjhHQ01LVyIsIml2IjoiM0ZRM0FsLWJWdWhmcEIyQyJ9.dhVipWbzIdsINttuZM4hnjpHvwEHf0VsVrOp4GAg01g.dk7dUyt1Qj13Pipw.5Tt70ONATF0BZAS8dBkYmCV7AQUrfb8qmKNLmw.A6ton9MQjZg0b3C0QcW-hg",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwidGFnIjoiUHNpTGphZnJZNE16UlRmNlBPLTZfdyIsImFsZyI6IkExMjhHQ01LVyIsIml2IjoiSUFPbnd2ODR5YXFEaUxtbSJ9.swf92_LyCvjsvkynHTuMNXRl_MX2keU-fMDWIMezHG4.LOp9SVIXzs4yTnOtMyXZYQ.HUlXrzqJ1qXYl3vUA-ydezCg77WvJNtKdmZ3FPABoZw.8UYl1LOofQLAxHHvWqoTbg",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTkyQ0JDLUhTMzg0IiwidGFnIjoiWGRndHQ5dUVEMVlVeU1rVHl6M3lqZyIsImFsZyI6IkExMjhHQ01LVyIsIml2IjoiWF90V2RhSmh6X3J1SHJvQSJ9.JQ3dS1JSgzIFi5M9ig63FoFU1nHBTmPwXY_ovNE2m1JOSUvHtalmihIuraPDloCf.e920JVryUIWt7zJJQM-www.8DUrl4LmsxIEhRr9RLTHG9tBTOcwXqEbQHAJd_qMHzE.wHinoqGUhL4O7lx125kponpwNtlp8VGJ",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwidGFnIjoicGgyaTdoY0FWNlh3ZkQta1RHYlVXdyIsImFsZyI6IkExMjhHQ01LVyIsIml2IjoiaG41Smk4Wm1rUmRrSUxWVSJ9._bQlJXl22dhsBgYPhkxUyinBNi871teGWbviOueWj2PqG9OPxIc9SDS8a27YLSVDMircd5Q1Df28--vcXIABQA.DssmhrAg6w_f2VDaPpxTbQ.OGclEmqrxwvZqAfn7EgXlIfXgr0wiGvEbZz3zADnqJs.YZeP0uKVEiDl8VyC-s20YN-RbdyGNsbdtoGDP3eMof8",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiQTEyOEtXIn0.TEMcXEoY8WyqGjYs5GZgS-M_Niwu6wDY.i-26KtTt51Td6Iwd.wvhkagvPsLj3QxhPBbfH_th8OqxisUtme2UadQ.vlfvBPv3bw2Zk2H60JVNLQ",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTkyR0NNIiwiYWxnIjoiQTEyOEtXIn0.gPaR6mgQ9TUx05V6DRfgTQeZxl0ZSzBa5uQd-qw6yLs.MojplOD77FkMooS-.2yuD7dKR_C3sFbhgwiBccKKOF8DrSvNiwX7wPQ.qDKUbSvMnJv0qifjpWC14g",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiQTEyOEtXIn0.Fg-dgSkUW1KEaL5YDPoWHNL8fpX1WxWVLA9OOWsjIFhQVDKyUZI7BQ.mjRBpyJTZf7H-quf.YlNHezMadtaSKp23G-ozmYhHOeHwuJnvWGTtGg.YagnR7awBItUlMDo4uklvg",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiQTEyOEtXIn0.x1vYzUE-E2XBWva9OPuwtqfQaf9rlJCIBAyAe6N2q2kWfJrkxGxFsQ.gAwe78dyODFaoP2IOityAA.Yh5YfovkWxGBNAs1sVhvXow_2izHHsBiYEc9JYD6kVg.mio1p3ncp2wLEaEaRa7P0w",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTkyQ0JDLUhTMzg0IiwiYWxnIjoiQTEyOEtXIn0.szGrdnmF7D5put2aRBvSSFfp0vRgkRGYaafijJIqAF6PWd1IxsysZRV8aQkQOW1cB6d0fXsTfYM.Ru25LVOOk4xhaK-cIZ0ThA.pF9Ok5zot7elVqXFW5YYHV8MuF9gVGzpQnG1XDs_g_w.-7la0uwcNPpteev185pMHZjbVDXlrec8",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiYWxnIjoiQTEyOEtXIn0.cz-hRv0xR5CnOcnoRWNK8Q9poyVYzRCVTjfmEXQN6xPOZUkJ3zKNqb8Pir_FS0o2TVvxmIbuxeISeATTR2Ttx_YGCNgMkc93.SF5rEQT94lZR-UORcMKqGw.xphygoU7zE0ZggOczXCi_ytt-Evln8CL-7WLDlWcUHg.5h99r8xCCwP2PgDbZqzCJ13oFfB2vZWetD5qZjmmVho",
|
||||
},
|
||||
{
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTI4R0NNIiwidGFnIjoiVWR5WUVKdEJ5ZTA5dzdjclY0cXI1QSIsImFsZyI6IkExOTJHQ01LVyIsIml2IjoiZlBBV0QwUmdSbHlFdktQcCJ9.P1uTfTuH-imL-NJJMpuTRA.22yqZ1NIfx3KNPgc.hORWZaTSgni1FS-JT90vJly-cU37qTn-tWSqTg.gMN0ufXF92rSXupTtBNkhA",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTkyR0NNIiwidGFnIjoiOU9qX3B2LTJSNW5lZl9YbWVkUWltUSIsImFsZyI6IkExOTJHQ01LVyIsIml2IjoiY3BybGEwYUYzREVQNmFJTSJ9.6NVpAm_APiC7km2v-oNR8g23K9U_kf1-.jIg-p8tNwSvwxch0.1i-GPaxS4qR6Gy4tzeVtSdRFRSKQSMpmn-VhzA.qhFWPqtA6vVPl7OM3DThsA",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMjU2R0NNIiwidGFnIjoiOVc3THg3MVhGQVJCb3NaLVZ5dXc4ZyIsImFsZyI6IkExOTJHQ01LVyIsIml2IjoiZ1N4ZE5heFdBSVBRR0tHYiJ9.3YjPz6dVQwAtCekvtXiHZrooOUlmCsMSvyfwmGwdrOA.hA_C0IDJmGaRzsB0.W4l7OPqpFxiVOZTGfAlRktquyRTo4cEOk9KurQ.l4bGxOkO_ql_jlPo3Oz3TQ",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwidGFnIjoiOHJYbWl2WXFWZjNfbHhhd2NUbHJoUSIsImFsZyI6IkExOTJHQ01LVyIsIml2IjoiVXBWeXprVTNKcjEwYXRqYyJ9.8qft-Q_xqUbo5j_aVrVNHchooeLttR4Kb6j01O8k98M.hXO-5IKBYCL9UdwBFVm0tg.EBM4lCZX_K6tfqYmfoDxVPHcf6cT--AegXTTjfSqsIw.Of8xUvEQSh3xgFT3uENnAg",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTkyQ0JDLUhTMzg0IiwidGFnIjoiVnItSnVaX0tqV2hSWWMzdzFwZ3cwdyIsImFsZyI6IkExOTJHQ01LVyIsIml2IjoiRGg2R3dISVBVS3ljZGNZeCJ9.YSEDjCnGWr_n9H94AvLoRnwm6bdU9w6-Q67k-QQRVcKRd6673pgH9zEF9A9Dt6o1.gcmVN4kxqBuMq6c7GrK3UQ.vWzJb0He6OY1lhYYjYS7CLh55REAAq1O7yNN-ND4R5Q.OD0B6nwyFaDr_92ysDOtlVnJaeoIqhGw",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwidGFnIjoieEtad1BGYURpQ3NqUnBqZUprZHhmZyIsImFsZyI6IkExOTJHQ01LVyIsIml2IjoieTVHRFdteXdkb2R1SDJlYyJ9.AW0gbhWqlptOQ1y9aoNVwrTIIkBfrp33C2OWJsbrDRk6lhxg_IgFhMDTE37moReySGUtttC4CXQD_7etHmd3Hw.OvKXK-aRKlXHOpJQ9ZY_YQ.Ngv7WarDDvR2uBj_DavPAR3DYuIaygvSSdcHrc8-ZqM.MJ6ElitzFCKf_0h5fIJw8uOLC6ps7dKZPozF8juQmUY",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiQTE5MktXIn0.8qu63pppcSvp1vv37WrZ44qcCTg7dQMA.cDp-f8dJTrDEpZW4.H6OBJYs4UvFR_IZHLYQZxB6u9a0wOdAif2LNfQ.1dB-id0UIwRSlmwHx5BJCg",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTkyR0NNIiwiYWxnIjoiQTE5MktXIn0._FdoKQvC8qUs7K0upriEihUwztK8gOwonXpOxdIwrfs.UO38ok8gDdpLVa1T.x1GvHdVCy4fxoQRg-OQK4Ez3jDOvu9gllLPeEA.3dLeZGIprh_nHizOTVi1xw",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiQTE5MktXIn0.uzCJskgSIK6VkjJIu-dQi18biqaY0INc_A1Ehx0oESafgtR99_n4IA.W2eKK8Y14WwTowI_.J2cJC7R6Bz6maR0s1UBMPyRi5BebNUAmof4pvw.-7w6htAlc4iUsOJ6I04rFg",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiQTE5MktXIn0.gImQeQETp_6dfJypFDPLlv7c5pCzuq86U16gzrLiCXth6X9XfxJpvQ.YlC4MxjtLWrsyEvlFhvsqw.Vlpvmg9F3gkz4e1xG01Yl2RXx-jG99rF5UvCxOBXSLc.RZUrU_FoR5bG3M-j3GY0Dw",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTkyQ0JDLUhTMzg0IiwiYWxnIjoiQTE5MktXIn0.T2EfQ6Tu2wJyRMgZzfvBYmQNCCfdMudMrg86ibEMVAOUKJPtR3WMPEb_Syy9p2VjrLKRlv7nebo.GPc8VbarPPRtzIRATB8NsA.ugPCqLvVLwh55bWlwjsFkmWzJ31z5z-wuih2oJqmG_U.m7FY3EjvV6mKosEYJ5cY7ezFoVQoJS8X",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiYWxnIjoiQTE5MktXIn0.OgLMhZ-2ZhslQyHfzOfyC-qmT6bNg9AdpP59B4jtyxWkQu3eW475WCdiAjojjeyBtVRGQ5vOomwaOIFejY_IekzH6I_taii3.U9x44MF6Wyz5TIwIzwhoxQ.vK7yvSF2beKdNxNY_7n4XdF7JluCGZoxdFJyTJVkSmI.bXRlI8KL-g7gpprQxGmXjVYjYghhWJq7mlCfWI8q2uA",
|
||||
},
|
||||
{
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTI4R0NNIiwidGFnIjoiR3BjX3pfbjduZjJVZlEtWGdsaTBaQSIsImFsZyI6IkEyNTZHQ01LVyIsIml2IjoiUk40eUdhOVlvYlFhUmZ1TCJ9.Q4ukD6_hZpmASAVcqWJ9Wg.Zfhny_1WNdlp4fH-.3sekDCjkExQCcv28ZW4yrcFnz0vma3vgoenSXA.g8_Ird2Y0itTCDP61du-Yg",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTkyR0NNIiwidGFnIjoiWC05UkNVWVh4U3NRelcwelVJS01VUSIsImFsZyI6IkEyNTZHQ01LVyIsIml2IjoiY3JNMnJfa3RrdWpyQ1h5OSJ9.c0q2jCxxV4y1h9u_Xvn7FqUDnbkmNEG4.S_noOTZKuUo9z1l6.ez0RdA25vXMUGH96iXmj3DEVox0J7TasJMnzgg.RbuSPTte_NzTtEEokbc5Ig",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMjU2R0NNIiwidGFnIjoiWmwyaDFpUW11QWZWd2lJeVp5RHloZyIsImFsZyI6IkEyNTZHQ01LVyIsIml2Ijoib19xZmljb0N0NzNzRWo1QyJ9.NpJxRJ0aqcpekD6HU2u9e6_pL_11JXjWvjfeQnAKkZU.4c5qBcBBrMWi27Lf.NKwNIb4b6cRDJ1TwMKsPrjs7ADn6aNoBdQClVw.yNWmSSRBqQfIQObzj8zDqw",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwidGFnIjoiMXdwVEI3LWhjdzZUVXhCbVh2UzdhUSIsImFsZyI6IkEyNTZHQ01LVyIsIml2IjoiOUdIVnZJaDZ0a09vX2pHUSJ9.MFgIhp9mzlq9hoPqqKVKHJ3HL79EBYtV4iNhD63yqiU.UzW5iq8ou21VpZYJgKEN8A.1gOEzA4uAPvHP76GMfs9uLloAV10mKaxiZVAeL7iQA0.i1X_2i0bCAz-soXF9bI_zw",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTkyQ0JDLUhTMzg0IiwidGFnIjoiNThocUtsSk15Y1BFUEFRUlNfSzlNUSIsImFsZyI6IkEyNTZHQ01LVyIsIml2IjoiUDh3aTBWMTluVnZqNXpkOSJ9.FXidOWHNFJODO74Thq3J2cC-Z2B8UZkn7SikeosU0bUK6Jx_lzzmUZ-Lafadpdpj.iLfcDbpuBKFiSfiBzUQc7Q.VZK-aD7BFspqfvbwa0wE2wwWxdomzk2IKMetFe8bI44.7wC6rJRGa4x48xbYMd6NH9VzK8uNn4Cb",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwidGFnIjoicGcwOEpUcXdzMXdEaXBaRUlpVExoQSIsImFsZyI6IkEyNTZHQ01LVyIsIml2IjoiSlpodk9CdU1RUDFFZTZTNSJ9.wqVgTPm6TcYCTkpbwmn9sW4mgJROH2A3dIdSXo5oKIQUIVbQsmy7KXH8UYO2RS9slMGtb869C8o0My67GKg9dQ.ogrRiLlqjB1S5j-7a05OwA.2Y_LyqhU4S_RXMsB74bxcBacd23J2Sp5Lblw-sOkaUY.XGMiYoU-f3GaEzSvG41vpJP2DMGbeDFoWmkUGLUjc4M",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiQTI1NktXIn0.QiIZm9NYfahqYFIbiaoUhCCHjotHMkup.EsU0XLn4FjzzCILn.WuCoQkm9vzo95E7hxBtfYpt-Mooc_vmSTyzj6Q.NbeeYVy6gQPlmhoWDrZwaQ",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTkyR0NNIiwiYWxnIjoiQTI1NktXIn0.1ol3j_Lt0Os3UMe2Gypj0o8b77k0FSmqD7kNRNoMa9U.vZ2HMTgN2dgUd42h.JvNcy8-c8sYzOC089VtFSg2BOQx3YF8CqSTuJw.t03LRioWWKN3d7SjinU6SQ",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiQTI1NktXIn0.gbkk03l1gyrE9qGEMVtORiyyUqKsgzbqjLd8lw0RQ07WWn--TV4BgA.J8ThH4ac2UhSsMIP.g-W1piEGrdi3tNwQDJXpYm3fQjTf82mtVCrCOg.-vY05P4kiB9FgF2vwrSeXQ",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiQTI1NktXIn0.k86pQs7gmQIzuIWRFwesF32XY2xi1WbYxi7XUf_CYlOlehwGCTINHg.3NcC9VzfQgsECISKf4xy-g.v2amdo-rgeGsg-II_tvPukX9D-KAP27xxf2uQJ277Ws.E4LIE3fte3glAnPpnd8D9Q",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMTkyQ0JDLUhTMzg0IiwiYWxnIjoiQTI1NktXIn0.b8iN0Am3fCUvj7sBd7Z0lpfzBjh1MOgojV7J5rDfrcTU3b35RGYgEV1RdcrtUTBgUwITDjmU7jM.wsSDBFghDga_ERv36I2AOg.6uJsucCb2YReFOJGBdo4zidTIKLUmZBIXfm_M0AJpKk.YwdAfXI3HHcw2wLSnfCRtw4huZQtSKhz",
|
||||
"eyJ6aXAiOiJERUYiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwiYWxnIjoiQTI1NktXIn0.akY9pHCbkHPh5VpXIrX0At41XnJIKBR9iMMkf301vKeJNAZYJTxWzeJhFd-DhQ47tMctc3YYkwZkQ5I_9fGYb_f0oBcw4esh.JNwuuHud78h6S99NO1oBQQ.0RwckPYATBgvw67upkAQ1AezETHc-gh3rryz19i5ryc.3XClRTScgzfMgLCHxHHoRF8mm9VVGXv_Ahtx65PskKQ",
|
||||
},
|
||||
}
|
||||
|
||||
for i, msgs := range aesSampleMessages {
|
||||
for _, msg := range msgs {
|
||||
obj, err := ParseEncrypted(msg)
|
||||
if err != nil {
|
||||
t.Error("unable to parse message", msg, err)
|
||||
continue
|
||||
}
|
||||
plaintext, err := obj.Decrypt(aesTestKeys[i])
|
||||
if err != nil {
|
||||
t.Error("unable to decrypt message", msg, err)
|
||||
continue
|
||||
}
|
||||
if string(plaintext) != "Lorem ipsum dolor sit amet" {
|
||||
t.Error("plaintext is not what we expected for msg", msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test vectors generated with jose4j
|
||||
func TestSampleJose4jJWEMessagesECDH(t *testing.T) {
|
||||
ecTestKey := &ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: elliptic.P256(),
|
||||
X: fromBase64Int("weNJy2HscCSM6AEDTDg04biOvhFhyyWvOHQfeF_PxMQ"),
|
||||
Y: fromBase64Int("e8lnCO-AlStT-NJVX-crhB7QRYhiix03illJOVAOyck"),
|
||||
},
|
||||
D: fromBase64Int("VEmDZpDXXK8p8N0Cndsxs924q6nS1RXFASRl6BfUqdw"),
|
||||
}
|
||||
|
||||
ecSampleMessages := []string{
|
||||
"eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTEyOENCQy1IUzI1NiIsImVwayI6eyJrdHkiOiJFQyIsIngiOiJTQzAtRnJHUkVvVkpKSmg1TGhORmZqZnFXMC1XSUFyd3RZMzJzQmFQVVh3IiwieSI6ImFQMWlPRENveU9laTVyS1l2VENMNlRMZFN5UEdUN0djMnFsRnBwNXdiWFEiLCJjcnYiOiJQLTI1NiJ9fQ..3mifklTnTTGuA_etSUBBCw.dj8KFM8OlrQ3rT35nHcHZ7A5p84VB2OZb054ghSjS-M.KOIgnJjz87LGqMtikXGxXw",
|
||||
"eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTE5MkNCQy1IUzM4NCIsImVwayI6eyJrdHkiOiJFQyIsIngiOiJUaHRGc0lRZ1E5MkZOYWFMbUFDQURLbE93dmNGVlRORHc4ampfWlJidUxjIiwieSI6IjJmRDZ3UXc3YmpYTm1nVThXMGpFbnl5ZUZkX3Y4ZmpDa3l1R29vTFhGM0EiLCJjcnYiOiJQLTI1NiJ9fQ..90zFayMkKc-fQC_19f6P3A.P1Y_7lMnfkUQOXW_en31lKZ3zAn1nEYn6fXLjmyVPrQ.hrgwy1cePVfhMWT0h-crKTXldglHZ-4g",
|
||||
"eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTI1NkNCQy1IUzUxMiIsImVwayI6eyJrdHkiOiJFQyIsIngiOiI5R1Z6c3VKNWgySl96UURVUFR3WU5zUkFzVzZfY2RzN0pELVQ2RDREQ1ZVIiwieSI6InFZVGl1dVU4aTB1WFpoaS14VGlRNlZJQm5vanFoWENPVnpmWm1pR2lRTEUiLCJjcnYiOiJQLTI1NiJ9fQ..v2reRlDkIsw3eWEsTCc1NA.0qakrFdbhtBCTSl7EREf9sxgHBP9I-Xw29OTJYnrqP8.54ozViEBYYmRkcKp7d2Ztt4hzjQ9Vb5zCeijN_RQrcI",
|
||||
"eyJhbGciOiJFQ0RILUVTK0EyNTZLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiOElUemg3VVFaaUthTWtfME9qX1hFaHZENXpUWjE2Ti13WVdjeTJYUC1tdyIsInkiOiJPNUJiVEk0bUFpU005ZmpCejBRU3pXaU5vbnl3cWlQLUN0RGgwdnNGYXNRIiwiY3J2IjoiUC0yNTYifX0.D3DP3wqPvJv4TYYfhnfrOG6nsM-MMH_CqGfnOGjgdXHNF7xRwEJBOA.WL9Kz3gNYA7S5Rs5mKcXmA.EmQkXhO_nFqAwxJWaM0DH4s3pmCscZovB8YWJ3Ru4N8.Bf88uzwfxiyTjpejU5B0Ng",
|
||||
"eyJhbGciOiJFQ0RILUVTK0EyNTZLVyIsImVuYyI6IkExOTJDQkMtSFMzODQiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiMjlJMk4zRkF0UlBlNGhzYjRLWlhTbmVyV0wyTVhtSUN1LXJJaXhNSHpJQSIsInkiOiJvMjY1bzFReEdmbDhzMHQ0U1JROS00RGNpc3otbXh4NlJ6WVF4SktyeWpJIiwiY3J2IjoiUC0yNTYifX0.DRmsmXz6fCnLc_njDIKdpM7Oc4jTqd_yd9J94TOUksAstEUkAl9Ie3Wg-Ji_LzbdX2xRLXIimcw.FwJOHPQhnqKJCfxt1_qRnQ.ssx3q1ZYILsMTln5q-K8HVn93BVPI5ViusstKMxZzRs.zzcfzWNYSdNDdQ4CiHfymj0bePaAbVaT",
|
||||
"eyJhbGciOiJFQ0RILUVTK0EyNTZLVyIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiRUp6bTViQnRzVXJNYTl2Y1Q2d1hZRXI3ZjNMcjB0N1V4SDZuZzdGcFF0VSIsInkiOiJRYTNDSDllVTFXYjItdFdVSDN3Sk9fTDVMZXRsRUlMQWNkNE9XR2tFd0hZIiwiY3J2IjoiUC0yNTYifX0.5WxwluZpVWAOJdVrsnDIlEc4_wfRE1gXOaQyx_rKkElNz157Ykf-JsAD7aEvXfx--NKF4js5zYyjeCtxWBhRWPOoNNZJlqV_.Iuo82-qsP2S1SgQQklAnrw.H4wB6XoLKOKWCu6Y3LPAEuHkvyvr-xAh4IBm53uRF8g._fOLKq0bqDZ8KNjni_MJ4olHNaYz376dV9eNmp9O9PU",
|
||||
"eyJhbGciOiJFQ0RILUVTK0ExOTJLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiZktNSG5sRkoxajBTSnJ3WGtVWlpaX3BtWHdUQlJtcHhlaTkxdUpaczUycyIsInkiOiJLRkxKaXhEUTJQcjEybWp1aFdYb3pna2U1V3lhWnhmTWlxZkJ0OEJpbkRvIiwiY3J2IjoiUC0yNTYifX0.2LSD2Mw4tyYJyfsmpVmzBtJRd12jMEYGdlhFbaXIbKi5A33CGNQ1tg.s40aAjmZOvK8Us86FCBdHg.jpYSMAKp___oMCoWM495mTfbi_YC80ObeoCmGE3H_gs.A6V-jJJRY1yz24CaXGUbzg",
|
||||
"eyJhbGciOiJFQ0RILUVTK0ExOTJLVyIsImVuYyI6IkExOTJDQkMtSFMzODQiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiSDRxcFUzeWtuRktWRnV4SmxLa3NZSE5ieHF3aXM0WWtCVVFHVE1Td05JQSIsInkiOiJHb0lpRUZaUGRRSHJCbVR4ZTA3akJoZmxrdWNqUjVoX1QwNWVXc3Zib0prIiwiY3J2IjoiUC0yNTYifX0.KTrwwV2uzD--gf3PGG-kjEAGgi7u0eMqZPZfa4kpyFGm3x8t2m1NHdz3t9rfiqjuaqsxPKhF4gs.cu16fEOzYaSxhHu_Ht9w4g.BRJdxVBI9spVtY5KQ6gTR4CNcKvmLUMKZap0AO-RF2I.DZyUaa2p6YCIaYtjWOjC9GN_VIYgySlZ",
|
||||
"eyJhbGciOiJFQ0RILUVTK0ExOTJLVyIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoieDBYSGRkSGM2Q0ktSnlfbUVMOEZZRExhWnV0UkVFczR4c3BMQmcwZk1jbyIsInkiOiJEa0xzOUJGTlBkTTVTNkpLYVJ3cnV1TWMwcUFzWW9yNW9fZWp6NXBNVXFrIiwiY3J2IjoiUC0yNTYifX0.mfCxJ7JYIqTMqcAh5Vp2USF0eF7OhOeluqda7YagOUJNwxA9wC9o23DSoLUylfrZUfanZrJJJcG69awlv-LY7anOLHlp3Ht5.ec48A_JWb4qa_PVHWZaTfQ.kDAjIDb3LzJpfxNh-DiAmAuaKMYaOGSTb0rkiJLuVeY.oxGCpPlii4pr89XMk4b9s084LucTqPGU6TLbOW2MZoc",
|
||||
"eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQXB5TnlqU2d0bmRUcFg0eENYenNDRnZva1l3X18weXg2dGRUYzdPUUhIMCIsInkiOiJYUHdHMDVDaW1vOGlhWmxZbDNsMEp3ZllhY1FZWHFuM2RRZEJUWFpldDZBIiwiY3J2IjoiUC0yNTYifX0.yTA2PwK9IPqkaGPenZ9R-gOn9m9rvcSEfuX_Nm8AkuwHIYLzzYeAEA.ZW1F1iyHYKfo-YoanNaIVg.PouKQD94DlPA5lbpfGJXY-EJhidC7l4vSayVN2vVzvA.MexquqtGaXKUvX7WBmD4bA",
|
||||
"eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExOTJDQkMtSFMzODQiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiaDRWeGNzNVUzWk1fTlp4WmJxQ3hMTVB5UmEtR2ktSVNZa0xDTzE1RHJkZyIsInkiOiJFeVotS3dWNVE5OXlnWk5zU0lpSldpR3hqbXNLUk1WVE5sTTNSd1VYTFRvIiwiY3J2IjoiUC0yNTYifX0.wo56VISyL1QAbi2HLuVut5NGF2FvxKt7B8zHzJ3FpmavPozfbVZV08-GSYQ6jLQWJ4xsO80I4Kg.3_9Bo5ozvD96WHGhqp_tfQ.48UkJ6jk6WK70QItb2QZr0edKH7O-aMuVahTEeqyfW4.ulMlY2tbC341ct20YSmNdtc84FRz1I4g",
|
||||
"eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkEyNTZDQkMtSFM1MTIiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiN0xZRzZZWTJkel9ZaGNvNnRCcG1IX0tPREQ2X2hwX05tajdEc1c2RXgxcyIsInkiOiI5Y2lPeDcwUkdGT0tpVnBRX0NHQXB5NVlyeThDazBmUkpwNHVrQ2tjNmQ0IiwiY3J2IjoiUC0yNTYifX0.bWwW3J80k46HG1fQAZxUroko2OO8OKkeRavr_o3AnhJDMvp78OR229x-fZUaBm4uWv27_Yjm0X9T2H2lhlIli2Rl9v1PNC77.1NmsJBDGI1fDjRzyc4mtyA.9KfCFynQj7LmJq08qxAG4c-6ZPz1Lh3h3nUbgVwB0TI.cqech0d8XHzWfkWqgKZq1SlAfmO0PUwOsNVkuByVGWk",
|
||||
}
|
||||
|
||||
for _, msg := range ecSampleMessages {
|
||||
obj, err := ParseEncrypted(msg)
|
||||
if err != nil {
|
||||
t.Error("unable to parse message", msg, err)
|
||||
continue
|
||||
}
|
||||
plaintext, err := obj.Decrypt(ecTestKey)
|
||||
if err != nil {
|
||||
t.Error("unable to decrypt message", msg, err)
|
||||
continue
|
||||
}
|
||||
if string(plaintext) != "Lorem ipsum dolor sit amet." {
|
||||
t.Error("plaintext is not what we expected for msg", msg)
|
||||
}
|
||||
}
|
||||
}
|
661
vendor/gopkg.in/square/go-jose.v2/jwk_test.go
generated
vendored
661
vendor/gopkg.in/square/go-jose.v2/jwk_test.go
generated
vendored
@@ -1,661 +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 (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/square/go-jose.v2/json"
|
||||
)
|
||||
|
||||
// Test chain of two X.509 certificates
|
||||
var testCertificates, _ = x509.ParseCertificates(fromBase64Bytes(`
|
||||
MIIDfDCCAmSgAwIBAgIJANWAkzF7PA8/MA0GCSqGSIb3DQEBCwUAMFUxCzAJ
|
||||
BgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UEChMHY2VydGlnbzEQMA4G
|
||||
A1UECxMHZXhhbXBsZTEVMBMGA1UEAxMMZXhhbXBsZS1sZWFmMB4XDTE2MDYx
|
||||
MDIyMTQxMVoXDTIzMDQxNTIyMTQxMVowVTELMAkGA1UEBhMCVVMxCzAJBgNV
|
||||
BAgTAkNBMRAwDgYDVQQKEwdjZXJ0aWdvMRAwDgYDVQQLEwdleGFtcGxlMRUw
|
||||
EwYDVQQDEwxleGFtcGxlLWxlYWYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
||||
ggEKAoIBAQC7stSvfQyGuHw3v34fisqIdDXberrFoFk9ht/WdXgYzX2uLNKd
|
||||
sR/J5sbWSl8K/5djpzj31eIzqU69w8v7SChM5x9bouDsABHz3kZucx5cSafE
|
||||
gJojysBkcrq3VY+aJanzbL+qErYX+lhRpPcZK6JMWIwar8Y3B2la4yWwieec
|
||||
w2/WfEVvG0M/DOYKnR8QHFsfl3US1dnBM84czKPyt9r40gDk2XiH/lGts5a9
|
||||
4rAGvbr8IMCtq0mA5aH3Fx3mDSi3+4MZwygCAHrF5O5iSV9rEI+m2+7j2S+j
|
||||
HDUnvV+nqcpb9m6ENECnYX8FD2KcqlOjTmw8smDy09N2Np6i464lAgMBAAGj
|
||||
TzBNMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAsBgNVHREEJTAj
|
||||
hwR/AAABhxAAAAAAAAAAAAAAAAAAAAABgglsb2NhbGhvc3QwDQYJKoZIhvcN
|
||||
AQELBQADggEBAGM4aa/qrURUweZBIwZYv8O9b2+r4l0HjGAh982/B9sMlM05
|
||||
kojyDCUGvj86z18Lm8mKr4/y+i0nJ+vDIksEvfDuzw5ALAXGcBzPJKtICUf7
|
||||
LstA/n9NNpshWz0kld9ylnB5mbUzSFDncVyeXkEf5sGQXdIIZT9ChRBoiloS
|
||||
aa7dvBVCcsX1LGP2LWqKtD+7nUnw5qCwtyAVT8pthEUxFTpywoiJS5ZdzeEx
|
||||
8MNGvUeLFj2kleqPF78EioEQlSOxViCuctEtnQuPcDLHNFr10byTZY9roObi
|
||||
qdsJLMVvb2XliJjAqaPa9AkYwGE6xHw2ispwg64Rse0+AtKups19WIUwggNT
|
||||
MIICO6ADAgECAgkAqD4tCWKt9/AwDQYJKoZIhvcNAQELBQAwVTELMAkGA1UE
|
||||
BhMCVVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQKEwdjZXJ0aWdvMRAwDgYDVQQL
|
||||
EwdleGFtcGxlMRUwEwYDVQQDEwxleGFtcGxlLXJvb3QwHhcNMTYwNjEwMjIx
|
||||
NDExWhcNMjMwNDE1MjIxNDExWjBVMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
|
||||
Q0ExEDAOBgNVBAoTB2NlcnRpZ28xEDAOBgNVBAsTB2V4YW1wbGUxFTATBgNV
|
||||
BAMTDGV4YW1wbGUtcm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
||||
ggEBAMo4ShKI2MxDz/NQVxBbz0tbD5R5NcobA0NKkaPKLyMEpnWVY9ucyauM
|
||||
joNn1F568cfOoF0pm3700U8UTPt2MMxEHIi4mFG/OF8UF+Voh1J42Tb42lRo
|
||||
W5RRR3ogh4+7QB1G94nxkYddHAJ4QMhUJlLigFg8c6Ff/MxYODy9I7ilLFOM
|
||||
Zzsjx8fFpRKRXNQFt471P/V4WTSba7GzdTOJRyTZf/xipF36n8RoEQPvyde8
|
||||
pEAsCC4oDOrEiCTdxw8rRJVAU0Wr55XX+qjxyi55C6oykIC/BWR+lUqGd7IL
|
||||
Y2Uyt/OVxllt8b+KuVKNCfn4TFlfgizLWkJRs6JV9KuwJ20CAwEAAaMmMCQw
|
||||
DgYDVR0PAQH/BAQDAgIEMBIGA1UdEwEB/wQIMAYBAf8CAQAwDQYJKoZIhvcN
|
||||
AQELBQADggEBAIsQlTrm9NT6gts0cs4JHp8AutuMrvGyLpIUOlJcEybvgxaz
|
||||
LebIMGZek5w3yEJiCyCK9RdNDP3Kdc/+nM6PhvzfPOVo58+0tMCYyEpZVXhD
|
||||
zmasNDP4fMbiUpczvx5OwPw/KuhwD+1ITuZUQnQlqXgTYoj9n39+qlgUsHos
|
||||
WXHmfzd6Fcz96ADSXg54IL2cEoJ41Q3ewhA7zmWWPLMAl21aex2haiAmzqqN
|
||||
xXyfZTnGNnE3lkV1yVguOrqDZyMRdcxDFvxvtmEeMtYV2Mc/zlS9ccrcOkrc
|
||||
mZSDxthLu3UMl98NA2NrCGWwzJwpk36vQ0PRSbibsCMarFspP8zbIoU=`))
|
||||
|
||||
func TestCurveSize(t *testing.T) {
|
||||
size256 := curveSize(elliptic.P256())
|
||||
size384 := curveSize(elliptic.P384())
|
||||
size521 := curveSize(elliptic.P521())
|
||||
if size256 != 32 {
|
||||
t.Error("P-256 have 32 bytes")
|
||||
}
|
||||
if size384 != 48 {
|
||||
t.Error("P-384 have 48 bytes")
|
||||
}
|
||||
if size521 != 66 {
|
||||
t.Error("P-521 have 66 bytes")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoundtripRsaPrivate(t *testing.T) {
|
||||
jwk, err := fromRsaPrivateKey(rsaTestKey)
|
||||
if err != nil {
|
||||
t.Error("problem constructing JWK from rsa key", err)
|
||||
}
|
||||
|
||||
rsa2, err := jwk.rsaPrivateKey()
|
||||
if err != nil {
|
||||
t.Error("problem converting RSA private -> JWK", err)
|
||||
}
|
||||
|
||||
if rsa2.N.Cmp(rsaTestKey.N) != 0 {
|
||||
t.Error("RSA private N mismatch")
|
||||
}
|
||||
if rsa2.E != rsaTestKey.E {
|
||||
t.Error("RSA private E mismatch")
|
||||
}
|
||||
if rsa2.D.Cmp(rsaTestKey.D) != 0 {
|
||||
t.Error("RSA private D mismatch")
|
||||
}
|
||||
if len(rsa2.Primes) != 2 {
|
||||
t.Error("RSA private roundtrip expected two primes")
|
||||
}
|
||||
if rsa2.Primes[0].Cmp(rsaTestKey.Primes[0]) != 0 {
|
||||
t.Error("RSA private P mismatch")
|
||||
}
|
||||
if rsa2.Primes[1].Cmp(rsaTestKey.Primes[1]) != 0 {
|
||||
t.Error("RSA private Q mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRsaPrivateInsufficientPrimes(t *testing.T) {
|
||||
brokenRsaPrivateKey := rsa.PrivateKey{
|
||||
PublicKey: rsa.PublicKey{
|
||||
N: rsaTestKey.N,
|
||||
E: rsaTestKey.E,
|
||||
},
|
||||
D: rsaTestKey.D,
|
||||
Primes: []*big.Int{rsaTestKey.Primes[0]},
|
||||
}
|
||||
|
||||
_, err := fromRsaPrivateKey(&brokenRsaPrivateKey)
|
||||
if err != ErrUnsupportedKeyType {
|
||||
t.Error("expected unsupported key type error, got", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRsaPrivateExcessPrimes(t *testing.T) {
|
||||
brokenRsaPrivateKey := rsa.PrivateKey{
|
||||
PublicKey: rsa.PublicKey{
|
||||
N: rsaTestKey.N,
|
||||
E: rsaTestKey.E,
|
||||
},
|
||||
D: rsaTestKey.D,
|
||||
Primes: []*big.Int{
|
||||
rsaTestKey.Primes[0],
|
||||
rsaTestKey.Primes[1],
|
||||
big.NewInt(3),
|
||||
},
|
||||
}
|
||||
|
||||
_, err := fromRsaPrivateKey(&brokenRsaPrivateKey)
|
||||
if err != ErrUnsupportedKeyType {
|
||||
t.Error("expected unsupported key type error, got", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoundtripEcPublic(t *testing.T) {
|
||||
for i, ecTestKey := range []*ecdsa.PrivateKey{ecTestKey256, ecTestKey384, ecTestKey521} {
|
||||
jwk, err := fromEcPublicKey(&ecTestKey.PublicKey)
|
||||
|
||||
ec2, err := jwk.ecPublicKey()
|
||||
if err != nil {
|
||||
t.Error("problem converting ECDSA private -> JWK", i, err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(ec2.Curve, ecTestKey.Curve) {
|
||||
t.Error("ECDSA private curve mismatch", i)
|
||||
}
|
||||
if ec2.X.Cmp(ecTestKey.X) != 0 {
|
||||
t.Error("ECDSA X mismatch", i)
|
||||
}
|
||||
if ec2.Y.Cmp(ecTestKey.Y) != 0 {
|
||||
t.Error("ECDSA Y mismatch", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoundtripEcPrivate(t *testing.T) {
|
||||
for i, ecTestKey := range []*ecdsa.PrivateKey{ecTestKey256, ecTestKey384, ecTestKey521} {
|
||||
jwk, err := fromEcPrivateKey(ecTestKey)
|
||||
|
||||
ec2, err := jwk.ecPrivateKey()
|
||||
if err != nil {
|
||||
t.Error("problem converting ECDSA private -> JWK", i, err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(ec2.Curve, ecTestKey.Curve) {
|
||||
t.Error("ECDSA private curve mismatch", i)
|
||||
}
|
||||
if ec2.X.Cmp(ecTestKey.X) != 0 {
|
||||
t.Error("ECDSA X mismatch", i)
|
||||
}
|
||||
if ec2.Y.Cmp(ecTestKey.Y) != 0 {
|
||||
t.Error("ECDSA Y mismatch", i)
|
||||
}
|
||||
if ec2.D.Cmp(ecTestKey.D) != 0 {
|
||||
t.Error("ECDSA D mismatch", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoundtripX5C(t *testing.T) {
|
||||
jwk := JSONWebKey{
|
||||
Key: rsaTestKey,
|
||||
KeyID: "bar",
|
||||
Algorithm: "foo",
|
||||
Certificates: testCertificates,
|
||||
}
|
||||
|
||||
jsonbar, err := jwk.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Error("problem marshaling", err)
|
||||
}
|
||||
|
||||
var jwk2 JSONWebKey
|
||||
err = jwk2.UnmarshalJSON(jsonbar)
|
||||
if err != nil {
|
||||
t.Error("problem unmarshalling", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(testCertificates, jwk2.Certificates) {
|
||||
t.Error("Certificates not equal", jwk.Certificates, jwk2.Certificates)
|
||||
}
|
||||
|
||||
jsonbar2, err := jwk2.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Error("problem marshaling", err)
|
||||
}
|
||||
if !bytes.Equal(jsonbar, jsonbar2) {
|
||||
t.Error("roundtrip should not lose information")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshalUnmarshal(t *testing.T) {
|
||||
kid := "DEADBEEF"
|
||||
|
||||
for i, key := range []interface{}{ecTestKey256, ecTestKey384, ecTestKey521, rsaTestKey} {
|
||||
for _, use := range []string{"", "sig", "enc"} {
|
||||
jwk := JSONWebKey{Key: key, KeyID: kid, Algorithm: "foo"}
|
||||
if use != "" {
|
||||
jwk.Use = use
|
||||
}
|
||||
|
||||
jsonbar, err := jwk.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Error("problem marshaling", i, err)
|
||||
}
|
||||
|
||||
var jwk2 JSONWebKey
|
||||
err = jwk2.UnmarshalJSON(jsonbar)
|
||||
if err != nil {
|
||||
t.Error("problem unmarshalling", i, err)
|
||||
}
|
||||
|
||||
jsonbar2, err := jwk2.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Error("problem marshaling", i, err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(jsonbar, jsonbar2) {
|
||||
t.Error("roundtrip should not lose information", i)
|
||||
}
|
||||
if jwk2.KeyID != kid {
|
||||
t.Error("kid did not roundtrip JSON marshalling", i)
|
||||
}
|
||||
|
||||
if jwk2.Algorithm != "foo" {
|
||||
t.Error("alg did not roundtrip JSON marshalling", i)
|
||||
}
|
||||
|
||||
if jwk2.Use != use {
|
||||
t.Error("use did not roundtrip JSON marshalling", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshalNonPointer(t *testing.T) {
|
||||
type EmbedsKey struct {
|
||||
Key JSONWebKey
|
||||
}
|
||||
|
||||
keyJSON := []byte(`{
|
||||
"e": "AQAB",
|
||||
"kty": "RSA",
|
||||
"n": "vd7rZIoTLEe-z1_8G1FcXSw9CQFEJgV4g9V277sER7yx5Qjz_Pkf2YVth6wwwFJEmzc0hoKY-MMYFNwBE4hQHw"
|
||||
}`)
|
||||
var parsedKey JSONWebKey
|
||||
err := json.Unmarshal(keyJSON, &parsedKey)
|
||||
if err != nil {
|
||||
t.Errorf("Error unmarshalling key: %v", err)
|
||||
return
|
||||
}
|
||||
ek := EmbedsKey{
|
||||
Key: parsedKey,
|
||||
}
|
||||
out, err := json.Marshal(ek)
|
||||
if err != nil {
|
||||
t.Errorf("Error marshalling JSON: %v", err)
|
||||
return
|
||||
}
|
||||
expected := "{\"Key\":{\"kty\":\"RSA\",\"n\":\"vd7rZIoTLEe-z1_8G1FcXSw9CQFEJgV4g9V277sER7yx5Qjz_Pkf2YVth6wwwFJEmzc0hoKY-MMYFNwBE4hQHw\",\"e\":\"AQAB\"}}"
|
||||
if string(out) != expected {
|
||||
t.Error("Failed to marshal embedded non-pointer JWK properly:", string(out))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshalUnmarshalInvalid(t *testing.T) {
|
||||
// Make an invalid curve coordinate by creating a byte array that is one
|
||||
// byte too large, and setting the first byte to 1 (otherwise it's just zero).
|
||||
invalidCoord := make([]byte, curveSize(ecTestKey256.Curve)+1)
|
||||
invalidCoord[0] = 1
|
||||
|
||||
keys := []interface{}{
|
||||
// Empty keys
|
||||
&rsa.PrivateKey{},
|
||||
&ecdsa.PrivateKey{},
|
||||
// Invalid keys
|
||||
&ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
// Missing values in pub key
|
||||
Curve: elliptic.P256(),
|
||||
},
|
||||
},
|
||||
&ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
// Invalid curve
|
||||
Curve: nil,
|
||||
X: ecTestKey256.X,
|
||||
Y: ecTestKey256.Y,
|
||||
},
|
||||
},
|
||||
&ecdsa.PrivateKey{
|
||||
// Valid pub key, but missing priv key values
|
||||
PublicKey: ecTestKey256.PublicKey,
|
||||
},
|
||||
&ecdsa.PrivateKey{
|
||||
// Invalid pub key, values too large
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: ecTestKey256.Curve,
|
||||
X: big.NewInt(0).SetBytes(invalidCoord),
|
||||
Y: big.NewInt(0).SetBytes(invalidCoord),
|
||||
},
|
||||
D: ecTestKey256.D,
|
||||
},
|
||||
nil,
|
||||
}
|
||||
|
||||
for i, key := range keys {
|
||||
jwk := JSONWebKey{Key: key}
|
||||
_, err := jwk.MarshalJSON()
|
||||
if err == nil {
|
||||
t.Error("managed to serialize invalid key", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWebKeyVectorsInvalid(t *testing.T) {
|
||||
keys := []string{
|
||||
// Invalid JSON
|
||||
"{X",
|
||||
// Empty key
|
||||
"{}",
|
||||
// Invalid RSA keys
|
||||
`{"kty":"RSA"}`,
|
||||
`{"kty":"RSA","e":""}`,
|
||||
`{"kty":"RSA","e":"XXXX"}`,
|
||||
`{"kty":"RSA","d":"XXXX"}`,
|
||||
// Invalid EC keys
|
||||
`{"kty":"EC","crv":"ABC"}`,
|
||||
`{"kty":"EC","crv":"P-256"}`,
|
||||
`{"kty":"EC","crv":"P-256","d":"XXX"}`,
|
||||
`{"kty":"EC","crv":"ABC","d":"dGVzdA","x":"dGVzdA"}`,
|
||||
`{"kty":"EC","crv":"P-256","d":"dGVzdA","x":"dGVzdA"}`,
|
||||
}
|
||||
|
||||
for _, key := range keys {
|
||||
var jwk2 JSONWebKey
|
||||
err := jwk2.UnmarshalJSON([]byte(key))
|
||||
if err == nil {
|
||||
t.Error("managed to parse invalid key:", key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test vectors from RFC 7520
|
||||
var cookbookJWKs = []string{
|
||||
// EC Public
|
||||
stripWhitespace(`{
|
||||
"kty": "EC",
|
||||
"kid": "bilbo.baggins@hobbiton.example",
|
||||
"use": "sig",
|
||||
"crv": "P-521",
|
||||
"x": "AHKZLLOsCOzz5cY97ewNUajB957y-C-U88c3v13nmGZx6sYl_oJXu9
|
||||
A5RkTKqjqvjyekWF-7ytDyRXYgCF5cj0Kt",
|
||||
"y": "AdymlHvOiLxXkEhayXQnNCvDX4h9htZaCJN34kfmC6pV5OhQHiraVy
|
||||
SsUdaQkAgDPrwQrJmbnX9cwlGfP-HqHZR1"
|
||||
}`),
|
||||
|
||||
// EC Private
|
||||
stripWhitespace(`{
|
||||
"kty": "EC",
|
||||
"kid": "bilbo.baggins@hobbiton.example",
|
||||
"use": "sig",
|
||||
"crv": "P-521",
|
||||
"x": "AHKZLLOsCOzz5cY97ewNUajB957y-C-U88c3v13nmGZx6sYl_oJXu9
|
||||
A5RkTKqjqvjyekWF-7ytDyRXYgCF5cj0Kt",
|
||||
"y": "AdymlHvOiLxXkEhayXQnNCvDX4h9htZaCJN34kfmC6pV5OhQHiraVy
|
||||
SsUdaQkAgDPrwQrJmbnX9cwlGfP-HqHZR1",
|
||||
"d": "AAhRON2r9cqXX1hg-RoI6R1tX5p2rUAYdmpHZoC1XNM56KtscrX6zb
|
||||
KipQrCW9CGZH3T4ubpnoTKLDYJ_fF3_rJt"
|
||||
}`),
|
||||
|
||||
// RSA Public
|
||||
stripWhitespace(`{
|
||||
"kty": "RSA",
|
||||
"kid": "bilbo.baggins@hobbiton.example",
|
||||
"use": "sig",
|
||||
"n": "n4EPtAOCc9AlkeQHPzHStgAbgs7bTZLwUBZdR8_KuKPEHLd4rHVTeT
|
||||
-O-XV2jRojdNhxJWTDvNd7nqQ0VEiZQHz_AJmSCpMaJMRBSFKrKb2wqV
|
||||
wGU_NsYOYL-QtiWN2lbzcEe6XC0dApr5ydQLrHqkHHig3RBordaZ6Aj-
|
||||
oBHqFEHYpPe7Tpe-OfVfHd1E6cS6M1FZcD1NNLYD5lFHpPI9bTwJlsde
|
||||
3uhGqC0ZCuEHg8lhzwOHrtIQbS0FVbb9k3-tVTU4fg_3L_vniUFAKwuC
|
||||
LqKnS2BYwdq_mzSnbLY7h_qixoR7jig3__kRhuaxwUkRz5iaiQkqgc5g
|
||||
HdrNP5zw",
|
||||
"e": "AQAB"
|
||||
}`),
|
||||
|
||||
// RSA Private
|
||||
stripWhitespace(`{"kty":"RSA",
|
||||
"kid":"juliet@capulet.lit",
|
||||
"use":"enc",
|
||||
"n":"t6Q8PWSi1dkJj9hTP8hNYFlvadM7DflW9mWepOJhJ66w7nyoK1gPNqFMSQRy
|
||||
O125Gp-TEkodhWr0iujjHVx7BcV0llS4w5ACGgPrcAd6ZcSR0-Iqom-QFcNP
|
||||
8Sjg086MwoqQU_LYywlAGZ21WSdS_PERyGFiNnj3QQlO8Yns5jCtLCRwLHL0
|
||||
Pb1fEv45AuRIuUfVcPySBWYnDyGxvjYGDSM-AqWS9zIQ2ZilgT-GqUmipg0X
|
||||
OC0Cc20rgLe2ymLHjpHciCKVAbY5-L32-lSeZO-Os6U15_aXrk9Gw8cPUaX1
|
||||
_I8sLGuSiVdt3C_Fn2PZ3Z8i744FPFGGcG1qs2Wz-Q",
|
||||
"e":"AQAB",
|
||||
"d":"GRtbIQmhOZtyszfgKdg4u_N-R_mZGU_9k7JQ_jn1DnfTuMdSNprTeaSTyWfS
|
||||
NkuaAwnOEbIQVy1IQbWVV25NY3ybc_IhUJtfri7bAXYEReWaCl3hdlPKXy9U
|
||||
vqPYGR0kIXTQRqns-dVJ7jahlI7LyckrpTmrM8dWBo4_PMaenNnPiQgO0xnu
|
||||
ToxutRZJfJvG4Ox4ka3GORQd9CsCZ2vsUDmsXOfUENOyMqADC6p1M3h33tsu
|
||||
rY15k9qMSpG9OX_IJAXmxzAh_tWiZOwk2K4yxH9tS3Lq1yX8C1EWmeRDkK2a
|
||||
hecG85-oLKQt5VEpWHKmjOi_gJSdSgqcN96X52esAQ",
|
||||
"p":"2rnSOV4hKSN8sS4CgcQHFbs08XboFDqKum3sc4h3GRxrTmQdl1ZK9uw-PIHf
|
||||
QP0FkxXVrx-WE-ZEbrqivH_2iCLUS7wAl6XvARt1KkIaUxPPSYB9yk31s0Q8
|
||||
UK96E3_OrADAYtAJs-M3JxCLfNgqh56HDnETTQhH3rCT5T3yJws",
|
||||
"q":"1u_RiFDP7LBYh3N4GXLT9OpSKYP0uQZyiaZwBtOCBNJgQxaj10RWjsZu0c6I
|
||||
edis4S7B_coSKB0Kj9PaPaBzg-IySRvvcQuPamQu66riMhjVtG6TlV8CLCYK
|
||||
rYl52ziqK0E_ym2QnkwsUX7eYTB7LbAHRK9GqocDE5B0f808I4s",
|
||||
"dp":"KkMTWqBUefVwZ2_Dbj1pPQqyHSHjj90L5x_MOzqYAJMcLMZtbUtwKqvVDq3
|
||||
tbEo3ZIcohbDtt6SbfmWzggabpQxNxuBpoOOf_a_HgMXK_lhqigI4y_kqS1w
|
||||
Y52IwjUn5rgRrJ-yYo1h41KR-vz2pYhEAeYrhttWtxVqLCRViD6c",
|
||||
"dq":"AvfS0-gRxvn0bwJoMSnFxYcK1WnuEjQFluMGfwGitQBWtfZ1Er7t1xDkbN9
|
||||
GQTB9yqpDoYaN06H7CFtrkxhJIBQaj6nkF5KKS3TQtQ5qCzkOkmxIe3KRbBy
|
||||
mXxkb5qwUpX5ELD5xFc6FeiafWYY63TmmEAu_lRFCOJ3xDea-ots",
|
||||
"qi":"lSQi-w9CpyUReMErP1RsBLk7wNtOvs5EQpPqmuMvqW57NBUczScEoPwmUqq
|
||||
abu9V0-Py4dQ57_bapoKRu1R90bvuFnU63SHWEFglZQvJDMeAvmj4sm-Fp0o
|
||||
Yu_neotgQ0hzbI5gry7ajdYy9-2lNx_76aBZoOUu9HCJ-UsfSOI8"}`),
|
||||
|
||||
// X.509 Certificate Chain
|
||||
stripWhitespace(`{"kty":"RSA",
|
||||
"use":"sig",
|
||||
"kid":"1b94c",
|
||||
"n":"vrjOfz9Ccdgx5nQudyhdoR17V-IubWMeOZCwX_jj0hgAsz2J_pqYW08
|
||||
PLbK_PdiVGKPrqzmDIsLI7sA25VEnHU1uCLNwBuUiCO11_-7dYbsr4iJmG0Q
|
||||
u2j8DsVyT1azpJC_NG84Ty5KKthuCaPod7iI7w0LK9orSMhBEwwZDCxTWq4a
|
||||
YWAchc8t-emd9qOvWtVMDC2BXksRngh6X5bUYLy6AyHKvj-nUy1wgzjYQDwH
|
||||
MTplCoLtU-o-8SNnZ1tmRoGE9uJkBLdh5gFENabWnU5m1ZqZPdwS-qo-meMv
|
||||
VfJb6jJVWRpl2SUtCnYG2C32qvbWbjZ_jBPD5eunqsIo1vQ",
|
||||
"e":"AQAB",
|
||||
"x5c":
|
||||
["MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSIb3DQEBBQUAMGIxCzAJB
|
||||
gNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYD
|
||||
VQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1
|
||||
wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBg
|
||||
NVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDV
|
||||
QQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1w
|
||||
YmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL64zn8/QnH
|
||||
YMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66
|
||||
s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3WG7K+IiZhtELto/A7Fck9Ws6
|
||||
SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpn
|
||||
fajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/p1MtcIM42EA8BzE6ZQqC7VPq
|
||||
PvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVk
|
||||
aZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCKNb0CAwEAATANBgkqhkiG9w0BA
|
||||
QUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL
|
||||
+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9AqBNTqNgHq2G03X09266X5CpOe1
|
||||
zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL
|
||||
2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKVMJyf/RuP2SmmaIzmnw9JiSlYhzo
|
||||
4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTq
|
||||
gawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5MPvACWpkA6SdS4xSvdXK3IVfOWA=="]}`),
|
||||
}
|
||||
|
||||
// SHA-256 thumbprints of the above keys, hex-encoded
|
||||
var cookbookJWKThumbprints = []string{
|
||||
"747ae2dd2003664aeeb21e4753fe7402846170a16bc8df8f23a8cf06d3cbe793",
|
||||
"747ae2dd2003664aeeb21e4753fe7402846170a16bc8df8f23a8cf06d3cbe793",
|
||||
"f63838e96077ad1fc01c3f8405774dedc0641f558ebb4b40dccf5f9b6d66a932",
|
||||
"0fc478f8579325fcee0d4cbc6d9d1ce21730a6e97e435d6008fb379b0ebe47d4",
|
||||
"0ddb05bfedbec2070fa037324ba397396561d3425d6d69245570c261dc49dee3",
|
||||
}
|
||||
|
||||
func TestWebKeyVectorsValid(t *testing.T) {
|
||||
for _, key := range cookbookJWKs {
|
||||
var jwk2 JSONWebKey
|
||||
err := jwk2.UnmarshalJSON([]byte(key))
|
||||
if err != nil {
|
||||
t.Error("unable to parse valid key:", key, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestThumbprint(t *testing.T) {
|
||||
for i, key := range cookbookJWKs {
|
||||
var jwk2 JSONWebKey
|
||||
err := jwk2.UnmarshalJSON([]byte(key))
|
||||
if err != nil {
|
||||
t.Error("unable to parse valid key:", key, err)
|
||||
}
|
||||
|
||||
tp, err := jwk2.Thumbprint(crypto.SHA256)
|
||||
if err != nil {
|
||||
t.Error("unable to compute thumbprint:", key, err)
|
||||
}
|
||||
|
||||
tpHex := hex.EncodeToString(tp)
|
||||
if cookbookJWKThumbprints[i] != tpHex {
|
||||
t.Error("incorrect thumbprint:", i, cookbookJWKThumbprints[i], tpHex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshalUnmarshalJWKSet(t *testing.T) {
|
||||
jwk1 := JSONWebKey{Key: rsaTestKey, KeyID: "ABCDEFG", Algorithm: "foo"}
|
||||
jwk2 := JSONWebKey{Key: rsaTestKey, KeyID: "GFEDCBA", Algorithm: "foo"}
|
||||
var set JSONWebKeySet
|
||||
set.Keys = append(set.Keys, jwk1)
|
||||
set.Keys = append(set.Keys, jwk2)
|
||||
|
||||
jsonbar, err := json.Marshal(&set)
|
||||
if err != nil {
|
||||
t.Error("problem marshalling set", err)
|
||||
}
|
||||
var set2 JSONWebKeySet
|
||||
err = json.Unmarshal(jsonbar, &set2)
|
||||
if err != nil {
|
||||
t.Error("problem unmarshalling set", err)
|
||||
}
|
||||
jsonbar2, err := json.Marshal(&set2)
|
||||
if err != nil {
|
||||
t.Error("problem marshalling set", err)
|
||||
}
|
||||
if !bytes.Equal(jsonbar, jsonbar2) {
|
||||
t.Error("roundtrip should not lose information")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJWKSetKey(t *testing.T) {
|
||||
jwk1 := JSONWebKey{Key: rsaTestKey, KeyID: "ABCDEFG", Algorithm: "foo"}
|
||||
jwk2 := JSONWebKey{Key: rsaTestKey, KeyID: "GFEDCBA", Algorithm: "foo"}
|
||||
var set JSONWebKeySet
|
||||
set.Keys = append(set.Keys, jwk1)
|
||||
set.Keys = append(set.Keys, jwk2)
|
||||
k := set.Key("ABCDEFG")
|
||||
if len(k) != 1 {
|
||||
t.Errorf("method should return slice with one key not %d", len(k))
|
||||
}
|
||||
if k[0].KeyID != "ABCDEFG" {
|
||||
t.Error("method should return key with ID ABCDEFG")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJWKSymmetricKey(t *testing.T) {
|
||||
sample1 := `{"kty":"oct","alg":"A128KW","k":"GawgguFyGrWKav7AX4VKUg"}`
|
||||
sample2 := `{"kty":"oct","k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow","kid":"HMAC key used in JWS spec Appendix A.1 example"}`
|
||||
|
||||
var jwk1 JSONWebKey
|
||||
json.Unmarshal([]byte(sample1), &jwk1)
|
||||
|
||||
if jwk1.Algorithm != "A128KW" {
|
||||
t.Errorf("expected Algorithm to be A128KW, but was '%s'", jwk1.Algorithm)
|
||||
}
|
||||
expected1 := fromHexBytes("19ac2082e1721ab58a6afec05f854a52")
|
||||
if !bytes.Equal(jwk1.Key.([]byte), expected1) {
|
||||
t.Errorf("expected Key to be '%s', but was '%s'", hex.EncodeToString(expected1), hex.EncodeToString(jwk1.Key.([]byte)))
|
||||
}
|
||||
|
||||
var jwk2 JSONWebKey
|
||||
json.Unmarshal([]byte(sample2), &jwk2)
|
||||
|
||||
if jwk2.KeyID != "HMAC key used in JWS spec Appendix A.1 example" {
|
||||
t.Errorf("expected KeyID to be 'HMAC key used in JWS spec Appendix A.1 example', but was '%s'", jwk2.KeyID)
|
||||
}
|
||||
expected2 := fromHexBytes(`
|
||||
0323354b2b0fa5bc837e0665777ba68f5ab328e6f054c928a90f84b2d2502ebf
|
||||
d3fb5a92d20647ef968ab4c377623d223d2e2172052e4f08c0cd9af567d080a3`)
|
||||
if !bytes.Equal(jwk2.Key.([]byte), expected2) {
|
||||
t.Errorf("expected Key to be '%s', but was '%s'", hex.EncodeToString(expected2), hex.EncodeToString(jwk2.Key.([]byte)))
|
||||
}
|
||||
}
|
||||
|
||||
func TestJWKSymmetricRoundtrip(t *testing.T) {
|
||||
jwk1 := JSONWebKey{Key: []byte{1, 2, 3, 4}}
|
||||
marshaled, err := jwk1.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Error("failed to marshal valid JWK object", err)
|
||||
}
|
||||
|
||||
var jwk2 JSONWebKey
|
||||
err = jwk2.UnmarshalJSON(marshaled)
|
||||
if err != nil {
|
||||
t.Error("failed to unmarshal valid JWK object", err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(jwk1.Key.([]byte), jwk2.Key.([]byte)) {
|
||||
t.Error("round-trip of symmetric JWK gave different raw keys")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJWKSymmetricInvalid(t *testing.T) {
|
||||
invalid := JSONWebKey{}
|
||||
_, err := invalid.MarshalJSON()
|
||||
if err == nil {
|
||||
t.Error("excepted error on marshaling invalid symmetric JWK object")
|
||||
}
|
||||
|
||||
var jwk JSONWebKey
|
||||
err = jwk.UnmarshalJSON([]byte(`{"kty":"oct"}`))
|
||||
if err == nil {
|
||||
t.Error("excepted error on unmarshaling invalid symmetric JWK object")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJWKValid(t *testing.T) {
|
||||
bigInt := big.NewInt(0)
|
||||
eccPub := ecdsa.PublicKey{elliptic.P256(), bigInt, bigInt}
|
||||
rsaPub := rsa.PublicKey{bigInt, 1}
|
||||
cases := []struct {
|
||||
key interface{}
|
||||
expectedValidity bool
|
||||
}{
|
||||
{nil, false},
|
||||
{&ecdsa.PublicKey{}, false},
|
||||
{&eccPub, true},
|
||||
{&ecdsa.PrivateKey{}, false},
|
||||
{&ecdsa.PrivateKey{eccPub, bigInt}, true},
|
||||
{&rsa.PublicKey{}, false},
|
||||
{&rsaPub, true},
|
||||
{&rsa.PrivateKey{}, false},
|
||||
{&rsa.PrivateKey{rsaPub, bigInt, []*big.Int{bigInt, bigInt}, rsa.PrecomputedValues{}}, true},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
k := &JSONWebKey{Key: tc.key}
|
||||
if valid := k.Valid(); valid != tc.expectedValidity {
|
||||
t.Errorf("expected Valid to return %t, got %t", tc.expectedValidity, valid)
|
||||
}
|
||||
}
|
||||
}
|
312
vendor/gopkg.in/square/go-jose.v2/jws_test.go
generated
vendored
312
vendor/gopkg.in/square/go-jose.v2/jws_test.go
generated
vendored
@@ -1,312 +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/x509"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEmbeddedHMAC(t *testing.T) {
|
||||
// protected: {"alg":"HS256", "jwk":{"kty":"oct", "k":"MTEx"}}, aka HMAC key.
|
||||
msg := `{"payload":"TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ","protected":"eyJhbGciOiJIUzI1NiIsICJqd2siOnsia3R5Ijoib2N0IiwgImsiOiJNVEV4In19","signature":"lvo41ZZsuHwQvSh0uJtEXRR3vmuBJ7in6qMoD7p9jyo"}`
|
||||
|
||||
_, err := ParseSigned(msg)
|
||||
if err == nil {
|
||||
t.Error("should not allow parsing JWS with embedded JWK with HMAC key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompactParseJWS(t *testing.T) {
|
||||
// Should parse
|
||||
msg := "eyJhbGciOiJYWVoifQ.cGF5bG9hZA.c2lnbmF0dXJl"
|
||||
_, err := ParseSigned(msg)
|
||||
if err != nil {
|
||||
t.Error("Unable to parse valid message:", err)
|
||||
}
|
||||
|
||||
// Messages that should fail to parse
|
||||
failures := []string{
|
||||
// Not enough parts
|
||||
"eyJhbGciOiJYWVoifQ.cGF5bG9hZA",
|
||||
// Invalid signature
|
||||
"eyJhbGciOiJYWVoifQ.cGF5bG9hZA.////",
|
||||
// Invalid payload
|
||||
"eyJhbGciOiJYWVoifQ.////.c2lnbmF0dXJl",
|
||||
// Invalid header
|
||||
"////.eyJhbGciOiJYWVoifQ.c2lnbmF0dXJl",
|
||||
// Invalid header
|
||||
"cGF5bG9hZA.cGF5bG9hZA.c2lnbmF0dXJl",
|
||||
}
|
||||
|
||||
for i := range failures {
|
||||
_, err = ParseSigned(failures[i])
|
||||
if err == nil {
|
||||
t.Error("Able to parse invalid message")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFullParseJWS(t *testing.T) {
|
||||
// Messages that should succeed to parse
|
||||
successes := []string{
|
||||
"{\"payload\":\"CUJD\",\"signatures\":[{\"protected\":\"e30\",\"header\":{\"kid\":\"XYZ\"},\"signature\":\"CUJD\"},{\"protected\":\"e30\",\"signature\":\"CUJD\"}]}",
|
||||
}
|
||||
|
||||
for i := range successes {
|
||||
_, err := ParseSigned(successes[i])
|
||||
if err != nil {
|
||||
t.Error("Unble to parse valid message", err, successes[i])
|
||||
}
|
||||
}
|
||||
|
||||
// Messages that should fail to parse
|
||||
failures := []string{
|
||||
// Empty
|
||||
"{}",
|
||||
// Invalid JSON
|
||||
"{XX",
|
||||
// Invalid protected header
|
||||
"{\"payload\":\"CUJD\",\"signatures\":[{\"protected\":\"CUJD\",\"header\":{\"kid\":\"XYZ\"},\"signature\":\"CUJD\"}]}",
|
||||
// Invalid protected header
|
||||
"{\"payload\":\"CUJD\",\"protected\":\"CUJD\",\"header\":{\"kid\":\"XYZ\"},\"signature\":\"CUJD\"}",
|
||||
// Invalid protected header
|
||||
"{\"payload\":\"CUJD\",\"signatures\":[{\"protected\":\"###\",\"header\":{\"kid\":\"XYZ\"},\"signature\":\"CUJD\"}]}",
|
||||
// Invalid payload
|
||||
"{\"payload\":\"###\",\"signatures\":[{\"protected\":\"CUJD\",\"header\":{\"kid\":\"XYZ\"},\"signature\":\"CUJD\"}]}",
|
||||
// Invalid payload
|
||||
"{\"payload\":\"CUJD\",\"signatures\":[{\"protected\":\"e30\",\"header\":{\"kid\":\"XYZ\"},\"signature\":\"###\"}]}",
|
||||
}
|
||||
|
||||
for i := range failures {
|
||||
_, err := ParseSigned(failures[i])
|
||||
if err == nil {
|
||||
t.Error("Able to parse invalid message", err, failures[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRejectUnprotectedJWSNonce(t *testing.T) {
|
||||
// No need to test compact, since that's always protected
|
||||
|
||||
// Flattened JSON
|
||||
input := `{
|
||||
"header": { "nonce": "should-cause-an-error" },
|
||||
"payload": "does-not-matter",
|
||||
"signature": "does-not-matter"
|
||||
}`
|
||||
_, err := ParseSigned(input)
|
||||
if err == nil {
|
||||
t.Error("JWS with an unprotected nonce parsed as valid.")
|
||||
} else if err != ErrUnprotectedNonce {
|
||||
t.Errorf("Improper error for unprotected nonce: %v", err)
|
||||
}
|
||||
|
||||
// Full JSON
|
||||
input = `{
|
||||
"payload": "does-not-matter",
|
||||
"signatures": [{
|
||||
"header": { "nonce": "should-cause-an-error" },
|
||||
"signature": "does-not-matter"
|
||||
}]
|
||||
}`
|
||||
_, err = ParseSigned(input)
|
||||
if err == nil {
|
||||
t.Error("JWS with an unprotected nonce parsed as valid.")
|
||||
} else if err != ErrUnprotectedNonce {
|
||||
t.Errorf("Improper error for unprotected nonce: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyFlattenedWithIncludedUnprotectedKey(t *testing.T) {
|
||||
input := `{
|
||||
"header": {
|
||||
"alg": "RS256",
|
||||
"jwk": {
|
||||
"e": "AQAB",
|
||||
"kty": "RSA",
|
||||
"n": "tSwgy3ORGvc7YJI9B2qqkelZRUC6F1S5NwXFvM4w5-M0TsxbFsH5UH6adigV0jzsDJ5imAechcSoOhAh9POceCbPN1sTNwLpNbOLiQQ7RD5mY_pSUHWXNmS9R4NZ3t2fQAzPeW7jOfF0LKuJRGkekx6tXP1uSnNibgpJULNc4208dgBaCHo3mvaE2HV2GmVl1yxwWX5QZZkGQGjNDZYnjFfa2DKVvFs0QbAk21ROm594kAxlRlMMrvqlf24Eq4ERO0ptzpZgm_3j_e4hGRD39gJS7kAzK-j2cacFQ5Qi2Y6wZI2p-FCq_wiYsfEAIkATPBiLKl_6d_Jfcvs_impcXQ"
|
||||
}
|
||||
},
|
||||
"payload": "Zm9vCg",
|
||||
"signature": "hRt2eYqBd_MyMRNIh8PEIACoFtmBi7BHTLBaAhpSU6zyDAFdEBaX7us4VB9Vo1afOL03Q8iuoRA0AT4akdV_mQTAQ_jhTcVOAeXPr0tB8b8Q11UPQ0tXJYmU4spAW2SapJIvO50ntUaqU05kZd0qw8-noH1Lja-aNnU-tQII4iYVvlTiRJ5g8_CADsvJqOk6FcHuo2mG643TRnhkAxUtazvHyIHeXMxydMMSrpwUwzMtln4ZJYBNx4QGEq6OhpAD_VSp-w8Lq5HOwGQoNs0bPxH1SGrArt67LFQBfjlVr94E1sn26p4vigXm83nJdNhWAMHHE9iV67xN-r29LT-FjA"
|
||||
}`
|
||||
|
||||
jws, err := ParseSigned(input)
|
||||
if err != nil {
|
||||
t.Error("Unable to parse valid message.")
|
||||
}
|
||||
if len(jws.Signatures) != 1 {
|
||||
t.Error("Too many or too few signatures.")
|
||||
}
|
||||
sig := jws.Signatures[0]
|
||||
if sig.Header.JSONWebKey == nil {
|
||||
t.Error("No JWK in signature header.")
|
||||
}
|
||||
payload, err := jws.Verify(sig.Header.JSONWebKey)
|
||||
if err != nil {
|
||||
t.Errorf("Signature did not validate: %v", err)
|
||||
}
|
||||
if string(payload) != "foo\n" {
|
||||
t.Errorf("Payload was incorrect: '%s' should have been 'foo\\n'", string(payload))
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyFlattenedWithPrivateProtected(t *testing.T) {
|
||||
// The protected field contains a Private Header Parameter name, per
|
||||
// https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#section-4
|
||||
// Base64-decoded, it's '{"nonce":"8HIepUNFZUa-exKTrXVf4g"}'
|
||||
input := `{"header":{"alg":"RS256","jwk":{"kty":"RSA","n":"7ixeydcbxxppzxrBphrW1atUiEZqTpiHDpI-79olav5XxAgWolHmVsJyxzoZXRxmtED8PF9-EICZWBGdSAL9ZTD0hLUCIsPcpdgT_LqNW3Sh2b2caPL2hbMF7vsXvnCGg9varpnHWuYTyRrCLUF9vM7ES-V3VCYTa7LcCSRm56Gg9r19qar43Z9kIKBBxpgt723v2cC4bmLmoAX2s217ou3uCpCXGLOeV_BesG4--Nl3pso1VhCfO85wEWjmW6lbv7Kg4d7Jdkv5DjDZfJ086fkEAYZVYGRpIgAvJBH3d3yKDCrSByUEud1bWuFjQBmMaeYOrVDXO_mbYg5PwUDMhw","e":"AQAB"}},"protected":"eyJub25jZSI6IjhISWVwVU5GWlVhLWV4S1RyWFZmNGcifQ","payload":"eyJjb250YWN0IjpbIm1haWx0bzpmb29AYmFyLmNvbSJdfQ","signature":"AyvVGMgXsQ1zTdXrZxE_gyO63pQgotL1KbI7gv6Wi8I7NRy0iAOkDAkWcTQT9pcCYApJ04lXfEDZfP5i0XgcFUm_6spxi5mFBZU-NemKcvK9dUiAbXvb4hB3GnaZtZiuVnMQUb_ku4DOaFFKbteA6gOYCnED_x7v0kAPHIYrQnvIa-KZ6pTajbV9348zgh9TL7NgGIIsTcMHd-Jatr4z1LQ0ubGa8tS300hoDhVzfoDQaEetYjCo1drR1RmdEN1SIzXdHOHfubjA3ZZRbrF_AJnNKpRRoIwzu1VayOhRmdy1qVSQZq_tENF4VrQFycEL7DhG7JLoXC4T2p1urwMlsw"}`
|
||||
|
||||
jws, err := ParseSigned(input)
|
||||
if err != nil {
|
||||
t.Error("Unable to parse valid message.")
|
||||
}
|
||||
if len(jws.Signatures) != 1 {
|
||||
t.Error("Too many or too few signatures.")
|
||||
}
|
||||
sig := jws.Signatures[0]
|
||||
if sig.Header.JSONWebKey == nil {
|
||||
t.Error("No JWK in signature header.")
|
||||
}
|
||||
payload, err := jws.Verify(sig.Header.JSONWebKey)
|
||||
if err != nil {
|
||||
t.Errorf("Signature did not validate: %v", err)
|
||||
}
|
||||
expected := "{\"contact\":[\"mailto:foo@bar.com\"]}"
|
||||
if string(payload) != expected {
|
||||
t.Errorf("Payload was incorrect: '%s' should have been '%s'", string(payload), expected)
|
||||
}
|
||||
}
|
||||
|
||||
// Test vectors generated with nimbus-jose-jwt
|
||||
func TestSampleNimbusJWSMessagesRSA(t *testing.T) {
|
||||
rsaPublicKey, err := x509.ParsePKIXPublicKey(fromBase64Bytes(`
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3aLSGwbeX0ZA2Ha+EvELaIFGzO
|
||||
91+Q15JQc/tdGdCgGW3XAbrh7ZUhDh1XKzbs+UOQxqn3Eq4YOx18IG0WsJSuCaHQIxnDlZ
|
||||
t/GP8WLwjMC0izlJLm2SyfM/EEoNpmTC3w6MQ2dHK7SZ9Zoq+sKijQd+V7CYdr8zHMpDrd
|
||||
NKoEcR0HjmvzzdMoUChhkGH5TaNbZyollULTggepaYUKS8QphqdSDMWiSetKG+g6V87lv6
|
||||
CVYyK1FF6g7Esp5OOj5pNn3/bmF+7V+b7TvK91NCIlURCjE9toRgNoIP4TDnWRn/vvfZ3G
|
||||
zNrtWmlizqz3r5KdvIs71ahWgMUSD4wfazrwIDAQAB`))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
rsaSampleMessages := []string{
|
||||
"eyJhbGciOiJSUzI1NiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.YHX849fvekz6wJGeyqnQhFqyHFcUXNJKj3o2w3ddR46YLlsCopUJrlifRU_ZuTWzpYxt5oC--T2eoqMhlCvltSWrE5_1_EumqiMfAYsZULx9E6Jns7q3w7mttonYFSIh7aR3-yg2HMMfTCgoAY1y_AZ4VjXwHDcZ5gu1oZDYgvZF4uXtCmwT6e5YtR1m8abiWPF8BgoTG_BD3KV6ClLj_QQiNFdfdxAMDw7vKVOKG1T7BFtz6cDs2Q3ILS4To5E2IjcVSSYS8mi77EitCrWmrqbK_G3WCdKeUFGnMnyuKXaCDy_7FLpAZ6Z5RomRr5iskXeJZdZqIKcJV8zl4fpsPA",
|
||||
"eyJhbGciOiJSUzM4NCJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.meyfoOTjAAjXHFYiNlU7EEnsYtbeUYeEglK6BL_cxISEr2YAGLr1Gwnn2HnucTnH6YilyRio7ZC1ohy_ZojzmaljPHqpr8kn1iqNFu9nFE2M16ZPgJi38-PGzppcDNliyzOQO-c7L-eA-v8Gfww5uyRaOJdiWg-hUJmeGBIngPIeLtSVmhJtz8oTeqeNdUOqQv7f7VRCuvagLhW1PcEM91VUS-gS0WEUXoXWZ2lp91No0v1O24izgX3__FKiX_16XhrOfAgJ82F61vjbTIQYwhexHPZyYTlXYt_scNRzFGhSKeGFin4zVdFLOXWJqKWdUd5IrDP5Nya3FSoWbWDXAg",
|
||||
"eyJhbGciOiJSUzUxMiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.rQPz0PDh8KyE2AX6JorgI0MLwv-qi1tcWlz6tuZuWQG1hdrlzq5tR1tQg1evYNc_SDDX87DWTSKXT7JEqhKoFixLfZa13IJrOc7FB8r5ZLx7OwOBC4F--OWrvxMA9Y3MTJjPN3FemQePUo-na2vNUZv-YgkcbuOgbO3hTxwQ7j1JGuqy-YutXOFnccdXvntp3t8zYZ4Mg1It_IyL9pzgGqHIEmMV1pCFGHsDa-wStB4ffmdhrADdYZc0q_SvxUdobyC_XzZCz9ENzGIhgwYxyyrqg7kjqUGoKmCLmoSlUFW7goTk9IC5SXdUyLPuESxOWNfHoRClGav230GYjPFQFA",
|
||||
"eyJhbGciOiJQUzI1NiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.UTtxjsv_6x4CdlAmZfAW6Lun3byMjJbcwRp_OlPH2W4MZaZar7aql052mIB_ddK45O9VUz2aphYVRvKPZY8WHmvlTUU30bk0z_cDJRYB9eIJVMOiRCYj0oNkz1iEZqsP0YgngxwuUDv4Q4A6aJ0Bo5E_rZo3AnrVHMHUjPp_ZRRSBFs30tQma1qQ0ApK4Gxk0XYCYAcxIv99e78vldVRaGzjEZmQeAVZx4tGcqZP20vG1L84nlhSGnOuZ0FhR8UjRFLXuob6M7EqtMRoqPgRYw47EI3fYBdeSivAg98E5S8R7R1NJc7ef-l03RvfUSY0S3_zBq_4PlHK6A-2kHb__w",
|
||||
"eyJhbGciOiJSUzM4NCJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.meyfoOTjAAjXHFYiNlU7EEnsYtbeUYeEglK6BL_cxISEr2YAGLr1Gwnn2HnucTnH6YilyRio7ZC1ohy_ZojzmaljPHqpr8kn1iqNFu9nFE2M16ZPgJi38-PGzppcDNliyzOQO-c7L-eA-v8Gfww5uyRaOJdiWg-hUJmeGBIngPIeLtSVmhJtz8oTeqeNdUOqQv7f7VRCuvagLhW1PcEM91VUS-gS0WEUXoXWZ2lp91No0v1O24izgX3__FKiX_16XhrOfAgJ82F61vjbTIQYwhexHPZyYTlXYt_scNRzFGhSKeGFin4zVdFLOXWJqKWdUd5IrDP5Nya3FSoWbWDXAg",
|
||||
"eyJhbGciOiJSUzUxMiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.rQPz0PDh8KyE2AX6JorgI0MLwv-qi1tcWlz6tuZuWQG1hdrlzq5tR1tQg1evYNc_SDDX87DWTSKXT7JEqhKoFixLfZa13IJrOc7FB8r5ZLx7OwOBC4F--OWrvxMA9Y3MTJjPN3FemQePUo-na2vNUZv-YgkcbuOgbO3hTxwQ7j1JGuqy-YutXOFnccdXvntp3t8zYZ4Mg1It_IyL9pzgGqHIEmMV1pCFGHsDa-wStB4ffmdhrADdYZc0q_SvxUdobyC_XzZCz9ENzGIhgwYxyyrqg7kjqUGoKmCLmoSlUFW7goTk9IC5SXdUyLPuESxOWNfHoRClGav230GYjPFQFA",
|
||||
}
|
||||
|
||||
for _, msg := range rsaSampleMessages {
|
||||
obj, err := ParseSigned(msg)
|
||||
if err != nil {
|
||||
t.Error("unable to parse message", msg, err)
|
||||
continue
|
||||
}
|
||||
payload, err := obj.Verify(rsaPublicKey)
|
||||
if err != nil {
|
||||
t.Error("unable to verify message", msg, err)
|
||||
continue
|
||||
}
|
||||
if string(payload) != "Lorem ipsum dolor sit amet" {
|
||||
t.Error("payload is not what we expected for msg", msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test vectors generated with nimbus-jose-jwt
|
||||
func TestSampleNimbusJWSMessagesEC(t *testing.T) {
|
||||
ecPublicKeyP256, err := x509.ParsePKIXPublicKey(fromBase64Bytes("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIg62jq6FyL1otEj9Up7S35BUrwGF9TVrAzrrY1rHUKZqYIGEg67u/imjgadVcr7y9Q32I0gB8W8FHqbqt696rA=="))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ecPublicKeyP384, err := x509.ParsePKIXPublicKey(fromBase64Bytes("MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEPXsVlqCtN2oTY+F+hFZm3M0ldYpb7IeeJM5wYmT0k1RaqzBFDhDMNnYK5Q5x+OyssZrAtHgYDFw02AVJhhng/eHRp7mqmL/vI3wbxJtrLKYldIbBA+9fYBQcKeibjlu5"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ecPublicKeyP521, err := x509.ParsePKIXPublicKey(fromBase64Bytes("MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAa2w3MMJ5FWD6tSf68G+Wy5jIhWXOD3IA7pE5IC/myQzo1lWcD8KS57SM6nm4POtPcxyLmDhL7FLuh8DKoIZyvtAAdK8+tOQP7XXRlT2bkvzIuazp05It3TAPu00YzTIpKfDlc19Y1lvf7etrbFqhShD92B+hHmhT4ddrdbPCBDW8hvU="))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ecPublicKeys := []interface{}{ecPublicKeyP256, ecPublicKeyP384, ecPublicKeyP521}
|
||||
|
||||
ecSampleMessages := []string{
|
||||
"eyJhbGciOiJFUzI1NiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.MEWJVlvGRQyzMEGOYm4rwuiwxrX-6LjnlbaRDAuhwmnBm2Gtn7pRpGXRTMFZUXsSGDz2L1p-Hz1qn8j9bFIBtQ",
|
||||
"eyJhbGciOiJFUzM4NCJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.nbdjPnJPYQtVNNdBIx8-KbFKplTxrz-hnW5UNhYUY7SBkwHK4NZnqc2Lv4DXoA0aWHq9eiypgOh1kmyPWGEmqKAHUx0xdIEkBoHk3ZsbmhOQuq2jL_wcMUG6nTWNhLrB",
|
||||
"eyJhbGciOiJFUzUxMiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.AeYNFC1rwIgQv-5fwd8iRyYzvTaSCYTEICepgu9gRId-IW99kbSVY7yH0MvrQnqI-a0L8zwKWDR35fW5dukPAYRkADp3Y1lzqdShFcEFziUVGo46vqbiSajmKFrjBktJcCsfjKSaLHwxErF-T10YYPCQFHWb2nXJOOI3CZfACYqgO84g",
|
||||
}
|
||||
|
||||
for i, msg := range ecSampleMessages {
|
||||
obj, err := ParseSigned(msg)
|
||||
if err != nil {
|
||||
t.Error("unable to parse message", msg, err)
|
||||
continue
|
||||
}
|
||||
payload, err := obj.Verify(ecPublicKeys[i])
|
||||
if err != nil {
|
||||
t.Error("unable to verify message", msg, err)
|
||||
continue
|
||||
}
|
||||
if string(payload) != "Lorem ipsum dolor sit amet" {
|
||||
t.Error("payload is not what we expected for msg", msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test vectors generated with nimbus-jose-jwt
|
||||
func TestSampleNimbusJWSMessagesHMAC(t *testing.T) {
|
||||
hmacTestKey := fromHexBytes("DF1FA4F36FFA7FC42C81D4B3C033928D")
|
||||
|
||||
hmacSampleMessages := []string{
|
||||
"eyJhbGciOiJIUzI1NiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.W5tc_EUhxexcvLYEEOckyyvdb__M5DQIVpg6Nmk1XGM",
|
||||
"eyJhbGciOiJIUzM4NCJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.sBu44lXOJa4Nd10oqOdYH2uz3lxlZ6o32QSGHaoGdPtYTDG5zvSja6N48CXKqdAh",
|
||||
"eyJhbGciOiJIUzUxMiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.M0yR4tmipsORIix-BitIbxEPGaxPchDfj8UNOpKuhDEfnb7URjGvCKn4nOlyQ1z9mG1FKbwnqR1hOVAWSzAU_w",
|
||||
}
|
||||
|
||||
for _, msg := range hmacSampleMessages {
|
||||
obj, err := ParseSigned(msg)
|
||||
if err != nil {
|
||||
t.Error("unable to parse message", msg, err)
|
||||
continue
|
||||
}
|
||||
payload, err := obj.Verify(hmacTestKey)
|
||||
if err != nil {
|
||||
t.Error("unable to verify message", msg, err)
|
||||
continue
|
||||
}
|
||||
if string(payload) != "Lorem ipsum dolor sit amet" {
|
||||
t.Error("payload is not what we expected for msg", msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test vectors generated with nimbus-jose-jwt
|
||||
func TestErrorMissingPayloadJWS(t *testing.T) {
|
||||
_, err := (&rawJSONWebSignature{}).sanitized()
|
||||
if err == nil {
|
||||
t.Error("was able to parse message with missing payload")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "missing payload") {
|
||||
t.Errorf("unexpected error message, should contain 'missing payload': %s", err)
|
||||
}
|
||||
}
|
427
vendor/gopkg.in/square/go-jose.v2/signing_test.go
generated
vendored
427
vendor/gopkg.in/square/go-jose.v2/signing_test.go
generated
vendored
@@ -1,427 +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 (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/square/go-jose.v2/json"
|
||||
)
|
||||
|
||||
type staticNonceSource string
|
||||
|
||||
func (sns staticNonceSource) Nonce() (string, error) {
|
||||
return string(sns), nil
|
||||
}
|
||||
|
||||
func RoundtripJWS(sigAlg SignatureAlgorithm, serializer func(*JSONWebSignature) (string, error), corrupter func(*JSONWebSignature), signingKey interface{}, verificationKey interface{}, nonce string) error {
|
||||
opts := &SignerOptions{}
|
||||
if nonce != "" {
|
||||
opts.NonceSource = staticNonceSource(nonce)
|
||||
}
|
||||
|
||||
signer, err := NewSigner(SigningKey{Algorithm: sigAlg, Key: signingKey}, opts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error on new signer: %s", err)
|
||||
}
|
||||
|
||||
input := []byte("Lorem ipsum dolor sit amet")
|
||||
obj, err := signer.Sign(input)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error on sign: %s", err)
|
||||
}
|
||||
|
||||
msg, err := serializer(obj)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error on serialize: %s", err)
|
||||
}
|
||||
|
||||
obj, err = ParseSigned(msg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error on parse: %s", err)
|
||||
}
|
||||
|
||||
// (Maybe) mangle the object
|
||||
corrupter(obj)
|
||||
|
||||
output, err := obj.Verify(verificationKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error on verify: %s", err)
|
||||
}
|
||||
|
||||
// Check that verify works with embedded keys (if present)
|
||||
for i, sig := range obj.Signatures {
|
||||
if sig.Header.JSONWebKey != nil {
|
||||
_, err = obj.Verify(sig.Header.JSONWebKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error on verify with embedded key %d: %s", i, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the nonce correctly round-tripped (if present)
|
||||
if sig.Header.Nonce != nonce {
|
||||
return fmt.Errorf("Incorrect nonce returned: [%s]", sig.Header.Nonce)
|
||||
}
|
||||
}
|
||||
|
||||
if bytes.Compare(output, input) != 0 {
|
||||
return fmt.Errorf("input/output do not match, got '%s', expected '%s'", output, input)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestRoundtripsJWS(t *testing.T) {
|
||||
// Test matrix
|
||||
sigAlgs := []SignatureAlgorithm{RS256, RS384, RS512, PS256, PS384, PS512, HS256, HS384, HS512, ES256, ES384, ES512}
|
||||
|
||||
serializers := []func(*JSONWebSignature) (string, error){
|
||||
func(obj *JSONWebSignature) (string, error) { return obj.CompactSerialize() },
|
||||
func(obj *JSONWebSignature) (string, error) { return obj.FullSerialize(), nil },
|
||||
}
|
||||
|
||||
corrupter := func(obj *JSONWebSignature) {}
|
||||
|
||||
for _, alg := range sigAlgs {
|
||||
signingKey, verificationKey := GenerateSigningTestKey(alg)
|
||||
|
||||
for i, serializer := range serializers {
|
||||
err := RoundtripJWS(alg, serializer, corrupter, signingKey, verificationKey, "test_nonce")
|
||||
if err != nil {
|
||||
t.Error(err, alg, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoundtripsJWSCorruptSignature(t *testing.T) {
|
||||
// Test matrix
|
||||
sigAlgs := []SignatureAlgorithm{RS256, RS384, RS512, PS256, PS384, PS512, HS256, HS384, HS512, ES256, ES384, ES512}
|
||||
|
||||
serializers := []func(*JSONWebSignature) (string, error){
|
||||
func(obj *JSONWebSignature) (string, error) { return obj.CompactSerialize() },
|
||||
func(obj *JSONWebSignature) (string, error) { return obj.FullSerialize(), nil },
|
||||
}
|
||||
|
||||
corrupters := []func(*JSONWebSignature){
|
||||
func(obj *JSONWebSignature) {
|
||||
// Changes bytes in signature
|
||||
obj.Signatures[0].Signature[10]++
|
||||
},
|
||||
func(obj *JSONWebSignature) {
|
||||
// Set totally invalid signature
|
||||
obj.Signatures[0].Signature = []byte("###")
|
||||
},
|
||||
}
|
||||
|
||||
// Test all different configurations
|
||||
for _, alg := range sigAlgs {
|
||||
signingKey, verificationKey := GenerateSigningTestKey(alg)
|
||||
|
||||
for i, serializer := range serializers {
|
||||
for j, corrupter := range corrupters {
|
||||
err := RoundtripJWS(alg, serializer, corrupter, signingKey, verificationKey, "test_nonce")
|
||||
if err == nil {
|
||||
t.Error("failed to detect corrupt signature", err, alg, i, j)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignerWithBrokenRand(t *testing.T) {
|
||||
sigAlgs := []SignatureAlgorithm{RS256, RS384, RS512, PS256, PS384, PS512}
|
||||
|
||||
serializer := func(obj *JSONWebSignature) (string, error) { return obj.CompactSerialize() }
|
||||
corrupter := func(obj *JSONWebSignature) {}
|
||||
|
||||
// Break rand reader
|
||||
readers := []func() io.Reader{
|
||||
// Totally broken
|
||||
func() io.Reader { return bytes.NewReader([]byte{}) },
|
||||
// Not enough bytes
|
||||
func() io.Reader { return io.LimitReader(rand.Reader, 20) },
|
||||
}
|
||||
|
||||
defer resetRandReader()
|
||||
|
||||
for _, alg := range sigAlgs {
|
||||
signingKey, verificationKey := GenerateSigningTestKey(alg)
|
||||
for i, getReader := range readers {
|
||||
randReader = getReader()
|
||||
err := RoundtripJWS(alg, serializer, corrupter, signingKey, verificationKey, "test_nonce")
|
||||
if err == nil {
|
||||
t.Error("signer should fail if rand is broken", alg, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestJWSInvalidKey(t *testing.T) {
|
||||
signingKey0, verificationKey0 := GenerateSigningTestKey(RS256)
|
||||
_, verificationKey1 := GenerateSigningTestKey(ES256)
|
||||
|
||||
signer, err := NewSigner(SigningKey{Algorithm: RS256, Key: signingKey0}, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
input := []byte("Lorem ipsum dolor sit amet")
|
||||
obj, err := signer.Sign(input)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Must work with correct key
|
||||
_, err = obj.Verify(verificationKey0)
|
||||
if err != nil {
|
||||
t.Error("error on verify", err)
|
||||
}
|
||||
|
||||
// Must not work with incorrect key
|
||||
_, err = obj.Verify(verificationKey1)
|
||||
if err == nil {
|
||||
t.Error("verification should fail with incorrect key")
|
||||
}
|
||||
|
||||
// Must not work with invalid key
|
||||
_, err = obj.Verify("")
|
||||
if err == nil {
|
||||
t.Error("verification should fail with incorrect key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiRecipientJWS(t *testing.T) {
|
||||
sharedKey := []byte{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
}
|
||||
|
||||
signer, err := NewMultiSigner([]SigningKey{
|
||||
{RS256, rsaTestKey},
|
||||
{HS384, sharedKey},
|
||||
}, nil)
|
||||
|
||||
input := []byte("Lorem ipsum dolor sit amet")
|
||||
obj, err := signer.Sign(input)
|
||||
if err != nil {
|
||||
t.Fatal("error on sign: ", err)
|
||||
}
|
||||
|
||||
_, err = obj.CompactSerialize()
|
||||
if err == nil {
|
||||
t.Fatal("message with multiple recipient was compact serialized")
|
||||
}
|
||||
|
||||
msg := obj.FullSerialize()
|
||||
|
||||
obj, err = ParseSigned(msg)
|
||||
if err != nil {
|
||||
t.Fatal("error on parse: ", err)
|
||||
}
|
||||
|
||||
i, _, output, err := obj.VerifyMulti(&rsaTestKey.PublicKey)
|
||||
if err != nil {
|
||||
t.Fatal("error on verify: ", err)
|
||||
}
|
||||
|
||||
if i != 0 {
|
||||
t.Fatal("signature index should be 0 for RSA key")
|
||||
}
|
||||
|
||||
if bytes.Compare(output, input) != 0 {
|
||||
t.Fatal("input/output do not match", output, input)
|
||||
}
|
||||
|
||||
i, _, output, err = obj.VerifyMulti(sharedKey)
|
||||
if err != nil {
|
||||
t.Fatal("error on verify: ", err)
|
||||
}
|
||||
|
||||
if i != 1 {
|
||||
t.Fatal("signature index should be 1 for EC key")
|
||||
}
|
||||
|
||||
if bytes.Compare(output, input) != 0 {
|
||||
t.Fatal("input/output do not match", output, input)
|
||||
}
|
||||
}
|
||||
|
||||
func GenerateSigningTestKey(sigAlg SignatureAlgorithm) (sig, ver interface{}) {
|
||||
switch sigAlg {
|
||||
case RS256, RS384, RS512, PS256, PS384, PS512:
|
||||
sig = rsaTestKey
|
||||
ver = &rsaTestKey.PublicKey
|
||||
case HS256, HS384, HS512:
|
||||
sig, _, _ = randomKeyGenerator{size: 16}.genKey()
|
||||
ver = sig
|
||||
case ES256:
|
||||
key, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
sig = key
|
||||
ver = &key.PublicKey
|
||||
case ES384:
|
||||
key, _ := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||
sig = key
|
||||
ver = &key.PublicKey
|
||||
case ES512:
|
||||
key, _ := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
||||
sig = key
|
||||
ver = &key.PublicKey
|
||||
default:
|
||||
panic("Must update test case")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func TestInvalidSignerAlg(t *testing.T) {
|
||||
_, err := NewSigner(SigningKey{"XYZ", nil}, nil)
|
||||
if err == nil {
|
||||
t.Error("should not accept invalid algorithm")
|
||||
}
|
||||
|
||||
_, err = NewSigner(SigningKey{"XYZ", []byte{}}, nil)
|
||||
if err == nil {
|
||||
t.Error("should not accept invalid algorithm")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidJWS(t *testing.T) {
|
||||
signer, err := NewSigner(SigningKey{PS256, rsaTestKey}, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
obj, err := signer.Sign([]byte("Lorem ipsum dolor sit amet"))
|
||||
obj.Signatures[0].header = &rawHeader{
|
||||
Crit: []string{"TEST"},
|
||||
}
|
||||
|
||||
_, err = obj.Verify(&rsaTestKey.PublicKey)
|
||||
if err == nil {
|
||||
t.Error("should not verify message with unknown crit header")
|
||||
}
|
||||
|
||||
// Try without alg header
|
||||
obj.Signatures[0].protected = &rawHeader{}
|
||||
obj.Signatures[0].header = &rawHeader{}
|
||||
|
||||
_, err = obj.Verify(&rsaTestKey.PublicKey)
|
||||
if err == nil {
|
||||
t.Error("should not verify message with missing headers")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignerKid(t *testing.T) {
|
||||
kid := "DEADBEEF"
|
||||
payload := []byte("Lorem ipsum dolor sit amet")
|
||||
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Error("problem generating test signing key", err)
|
||||
}
|
||||
|
||||
basejwk := JSONWebKey{Key: key}
|
||||
jsonbar, err := basejwk.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Error("problem marshalling base JWK", err)
|
||||
}
|
||||
|
||||
var jsonmsi map[string]interface{}
|
||||
err = json.Unmarshal(jsonbar, &jsonmsi)
|
||||
if err != nil {
|
||||
t.Error("problem unmarshalling base JWK", err)
|
||||
}
|
||||
jsonmsi["kid"] = kid
|
||||
jsonbar2, err := json.Marshal(jsonmsi)
|
||||
if err != nil {
|
||||
t.Error("problem marshalling kided JWK", err)
|
||||
}
|
||||
|
||||
var jwk JSONWebKey
|
||||
err = jwk.UnmarshalJSON(jsonbar2)
|
||||
if err != nil {
|
||||
t.Error("problem unmarshalling kided JWK", err)
|
||||
}
|
||||
|
||||
signer, err := NewSigner(SigningKey{ES256, &jwk}, nil)
|
||||
if err != nil {
|
||||
t.Error("problem creating signer", err)
|
||||
}
|
||||
signed, err := signer.Sign(payload)
|
||||
|
||||
serialized := signed.FullSerialize()
|
||||
|
||||
parsed, err := ParseSigned(serialized)
|
||||
if err != nil {
|
||||
t.Error("problem parsing signed object", err)
|
||||
}
|
||||
|
||||
if parsed.Signatures[0].Header.KeyID != kid {
|
||||
t.Error("KeyID did not survive trip")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmbedJwk(t *testing.T) {
|
||||
var payload = []byte("Lorem ipsum dolor sit amet")
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Error("Failed to generate key")
|
||||
}
|
||||
|
||||
signer, err := NewSigner(SigningKey{ES256, key}, &SignerOptions{EmbedJWK: true})
|
||||
if err != nil {
|
||||
t.Error("Failed to create signer")
|
||||
}
|
||||
|
||||
object, err := signer.Sign(payload)
|
||||
if err != nil {
|
||||
t.Error("Failed to sign payload")
|
||||
}
|
||||
|
||||
object, err = ParseSigned(object.FullSerialize())
|
||||
if err != nil {
|
||||
t.Error("Failed to parse jws")
|
||||
}
|
||||
|
||||
if object.Signatures[0].protected.Jwk == nil {
|
||||
t.Error("JWK isn't set in protected header")
|
||||
}
|
||||
|
||||
// This time, sign and do not embed JWK in message
|
||||
signer, err = NewSigner(SigningKey{ES256, key}, &SignerOptions{EmbedJWK: false})
|
||||
|
||||
object, err = signer.Sign(payload)
|
||||
if err != nil {
|
||||
t.Error("Failed to sign payload")
|
||||
}
|
||||
|
||||
object, err = ParseSigned(object.FullSerialize())
|
||||
if err != nil {
|
||||
t.Error("Failed to parse jws")
|
||||
}
|
||||
|
||||
if object.Signatures[0].protected.Jwk != nil {
|
||||
t.Error("JWK is set in protected header")
|
||||
}
|
||||
}
|
131
vendor/gopkg.in/square/go-jose.v2/symmetric_test.go
generated
vendored
131
vendor/gopkg.in/square/go-jose.v2/symmetric_test.go
generated
vendored
@@ -1,131 +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 (
|
||||
"bytes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInvalidSymmetricAlgorithms(t *testing.T) {
|
||||
_, err := newSymmetricRecipient("XYZ", []byte{})
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should not accept invalid algorithm")
|
||||
}
|
||||
|
||||
enc := &symmetricKeyCipher{}
|
||||
_, err = enc.encryptKey([]byte{}, "XYZ")
|
||||
if err != ErrUnsupportedAlgorithm {
|
||||
t.Error("should not accept invalid algorithm")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAeadErrors(t *testing.T) {
|
||||
aead := &aeadContentCipher{
|
||||
keyBytes: 16,
|
||||
authtagBytes: 16,
|
||||
getAead: func(key []byte) (cipher.AEAD, error) {
|
||||
return nil, ErrCryptoFailure
|
||||
},
|
||||
}
|
||||
|
||||
parts, err := aead.encrypt([]byte{}, []byte{}, []byte{})
|
||||
if err != ErrCryptoFailure {
|
||||
t.Error("should handle aead failure")
|
||||
}
|
||||
|
||||
_, err = aead.decrypt([]byte{}, []byte{}, parts)
|
||||
if err != ErrCryptoFailure {
|
||||
t.Error("should handle aead failure")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidKey(t *testing.T) {
|
||||
gcm := newAESGCM(16).(*aeadContentCipher)
|
||||
_, err := gcm.getAead([]byte{})
|
||||
if err == nil {
|
||||
t.Error("should not accept invalid key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStaticKeyGen(t *testing.T) {
|
||||
key := make([]byte, 32)
|
||||
io.ReadFull(rand.Reader, key)
|
||||
|
||||
gen := &staticKeyGenerator{key: key}
|
||||
if gen.keySize() != len(key) {
|
||||
t.Error("static key generator reports incorrect size")
|
||||
}
|
||||
|
||||
generated, _, err := gen.genKey()
|
||||
if err != nil {
|
||||
t.Error("static key generator should always succeed", err)
|
||||
}
|
||||
if !bytes.Equal(generated, key) {
|
||||
t.Error("static key generator returns different data")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVectorsAESGCM(t *testing.T) {
|
||||
// Source: http://tools.ietf.org/html/draft-ietf-jose-json-web-encryption-29#appendix-A.1
|
||||
plaintext := []byte{
|
||||
84, 104, 101, 32, 116, 114, 117, 101, 32, 115, 105, 103, 110, 32,
|
||||
111, 102, 32, 105, 110, 116, 101, 108, 108, 105, 103, 101, 110, 99,
|
||||
101, 32, 105, 115, 32, 110, 111, 116, 32, 107, 110, 111, 119, 108,
|
||||
101, 100, 103, 101, 32, 98, 117, 116, 32, 105, 109, 97, 103, 105,
|
||||
110, 97, 116, 105, 111, 110, 46}
|
||||
|
||||
aad := []byte{
|
||||
101, 121, 74, 104, 98, 71, 99, 105, 79, 105, 74, 83, 85, 48, 69,
|
||||
116, 84, 48, 70, 70, 85, 67, 73, 115, 73, 109, 86, 117, 89, 121, 73,
|
||||
54, 73, 107, 69, 121, 78, 84, 90, 72, 81, 48, 48, 105, 102, 81}
|
||||
|
||||
expectedCiphertext := []byte{
|
||||
229, 236, 166, 241, 53, 191, 115, 196, 174, 43, 73, 109, 39, 122,
|
||||
233, 96, 140, 206, 120, 52, 51, 237, 48, 11, 190, 219, 186, 80, 111,
|
||||
104, 50, 142, 47, 167, 59, 61, 181, 127, 196, 21, 40, 82, 242, 32,
|
||||
123, 143, 168, 226, 73, 216, 176, 144, 138, 247, 106, 60, 16, 205,
|
||||
160, 109, 64, 63, 192}
|
||||
|
||||
expectedAuthtag := []byte{
|
||||
92, 80, 104, 49, 133, 25, 161, 215, 173, 101, 219, 211, 136, 91, 210, 145}
|
||||
|
||||
// Mock random reader
|
||||
randReader = bytes.NewReader([]byte{
|
||||
177, 161, 244, 128, 84, 143, 225, 115, 63, 180, 3, 255, 107, 154,
|
||||
212, 246, 138, 7, 110, 91, 112, 46, 34, 105, 47, 130, 203, 46, 122,
|
||||
234, 64, 252, 227, 197, 117, 252, 2, 219, 233, 68, 180, 225, 77, 219})
|
||||
defer resetRandReader()
|
||||
|
||||
enc := newAESGCM(32)
|
||||
key, _, _ := randomKeyGenerator{size: 32}.genKey()
|
||||
out, err := enc.encrypt(key, aad, plaintext)
|
||||
if err != nil {
|
||||
t.Error("Unable to encrypt:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if bytes.Compare(out.ciphertext, expectedCiphertext) != 0 {
|
||||
t.Error("Ciphertext did not match")
|
||||
}
|
||||
if bytes.Compare(out.tag, expectedAuthtag) != 0 {
|
||||
t.Error("Auth tag did not match")
|
||||
}
|
||||
}
|
70
vendor/gopkg.in/square/go-jose.v2/utils_test.go
generated
vendored
70
vendor/gopkg.in/square/go-jose.v2/utils_test.go
generated
vendored
@@ -1,70 +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/rand"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// Reset random reader to original value
|
||||
func resetRandReader() {
|
||||
randReader = rand.Reader
|
||||
}
|
||||
|
||||
// Build big int from hex-encoded string. Strips whitespace (for testing).
|
||||
func fromHexInt(base16 string) *big.Int {
|
||||
re := regexp.MustCompile(`\s+`)
|
||||
val, ok := new(big.Int).SetString(re.ReplaceAllString(base16, ""), 16)
|
||||
if !ok {
|
||||
panic("Invalid test data")
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// Build big int from base64-encoded string. Strips whitespace (for testing).
|
||||
func fromBase64Int(encoded string) *big.Int {
|
||||
re := regexp.MustCompile(`\s+`)
|
||||
val, err := base64.RawURLEncoding.DecodeString(re.ReplaceAllString(encoded, ""))
|
||||
if err != nil {
|
||||
panic("Invalid test data: " + err.Error())
|
||||
}
|
||||
return new(big.Int).SetBytes(val)
|
||||
}
|
||||
|
||||
// Decode hex-encoded string into byte array. Strips whitespace (for testing).
|
||||
func fromHexBytes(base16 string) []byte {
|
||||
re := regexp.MustCompile(`\s+`)
|
||||
val, err := hex.DecodeString(re.ReplaceAllString(base16, ""))
|
||||
if err != nil {
|
||||
panic("Invalid test data")
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// Decode base64-encoded string into byte array. Strips whitespace (for testing).
|
||||
func fromBase64Bytes(b64 string) []byte {
|
||||
re := regexp.MustCompile(`\s+`)
|
||||
val, err := base64.StdEncoding.DecodeString(re.ReplaceAllString(b64, ""))
|
||||
if err != nil {
|
||||
panic("Invalid test data")
|
||||
}
|
||||
return val
|
||||
}
|
Reference in New Issue
Block a user