~tsileo/blobstash

72a848dbf22653f37132d6f7eb7ab6c3c80476bd — Thomas Sileo 3 months ago c3d3d04
vendor,webauthn: upgrade to better webauthn lib
267 files changed, 7478 insertions(+), 60422 deletions(-)

M extras/cross_compile.sh -rwxr-xr-x => -rw-r--r--
M go.mod
M go.sum
M pkg/webauthn/webauthn.go
D vendor/github.com/cloudflare/cfssl/LICENSE
D vendor/github.com/cloudflare/cfssl/crypto/pkcs7/pkcs7.go
D vendor/github.com/cloudflare/cfssl/errors/doc.go
D vendor/github.com/cloudflare/cfssl/errors/error.go
D vendor/github.com/cloudflare/cfssl/errors/http.go
D vendor/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers.go
D vendor/github.com/cloudflare/cfssl/helpers/derhelpers/ed25519.go
D vendor/github.com/cloudflare/cfssl/helpers/helpers.go
D vendor/github.com/cloudflare/cfssl/log/log.go
D vendor/github.com/cloudflare/cfssl/revoke/revoke.go
D vendor/github.com/dgrijalva/jwt-go/.gitignore
D vendor/github.com/dgrijalva/jwt-go/.travis.yml
D vendor/github.com/dgrijalva/jwt-go/LICENSE
D vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md
D vendor/github.com/dgrijalva/jwt-go/README.md
D vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md
D vendor/github.com/dgrijalva/jwt-go/claims.go
D vendor/github.com/dgrijalva/jwt-go/doc.go
D vendor/github.com/dgrijalva/jwt-go/ecdsa.go
D vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go
D vendor/github.com/dgrijalva/jwt-go/errors.go
D vendor/github.com/dgrijalva/jwt-go/hmac.go
D vendor/github.com/dgrijalva/jwt-go/map_claims.go
D vendor/github.com/dgrijalva/jwt-go/none.go
D vendor/github.com/dgrijalva/jwt-go/parser.go
D vendor/github.com/dgrijalva/jwt-go/rsa.go
D vendor/github.com/dgrijalva/jwt-go/rsa_pss.go
D vendor/github.com/dgrijalva/jwt-go/rsa_utils.go
D vendor/github.com/dgrijalva/jwt-go/signing_method.go
D vendor/github.com/dgrijalva/jwt-go/token.go
D vendor/github.com/duo-labs/webauthn/LICENSE.txt
D vendor/github.com/duo-labs/webauthn/metadata/metadata.go
D vendor/github.com/duo-labs/webauthn/protocol/assertion.go
D vendor/github.com/duo-labs/webauthn/protocol/attestation.go
D vendor/github.com/duo-labs/webauthn/protocol/attestation_androidkey.go
D vendor/github.com/duo-labs/webauthn/protocol/attestation_packed.go
D vendor/github.com/duo-labs/webauthn/protocol/attestation_safetynet.go
D vendor/github.com/duo-labs/webauthn/protocol/attestation_tpm.go
D vendor/github.com/duo-labs/webauthn/protocol/attestation_u2f.go
D vendor/github.com/duo-labs/webauthn/protocol/authenticator.go
D vendor/github.com/duo-labs/webauthn/protocol/base64.go
D vendor/github.com/duo-labs/webauthn/protocol/challenge.go
D vendor/github.com/duo-labs/webauthn/protocol/client.go
D vendor/github.com/duo-labs/webauthn/protocol/credential.go
D vendor/github.com/duo-labs/webauthn/protocol/doc.go
D vendor/github.com/duo-labs/webauthn/protocol/entities.go
D vendor/github.com/duo-labs/webauthn/protocol/errors.go
D vendor/github.com/duo-labs/webauthn/protocol/extensions.go
D vendor/github.com/duo-labs/webauthn/protocol/googletpm/certinfo.go
D vendor/github.com/duo-labs/webauthn/protocol/googletpm/googletpm.go
D vendor/github.com/duo-labs/webauthn/protocol/googletpm/pubarea.go
D vendor/github.com/duo-labs/webauthn/protocol/options.go
D vendor/github.com/duo-labs/webauthn/protocol/signature_algorithms.go
D vendor/github.com/duo-labs/webauthn/protocol/webauthncose/ed25519.go
D vendor/github.com/duo-labs/webauthn/protocol/webauthncose/ed25519_go112.go
D vendor/github.com/duo-labs/webauthn/protocol/webauthncose/webauthncose.go
D vendor/github.com/duo-labs/webauthn/webauthn/authenticator.go
D vendor/github.com/duo-labs/webauthn/webauthn/credential.go
D vendor/github.com/duo-labs/webauthn/webauthn/doc.go
D vendor/github.com/duo-labs/webauthn/webauthn/login.go
D vendor/github.com/duo-labs/webauthn/webauthn/main.go
D vendor/github.com/duo-labs/webauthn/webauthn/registration.go
D vendor/github.com/duo-labs/webauthn/webauthn/session.go
D vendor/github.com/duo-labs/webauthn/webauthn/user.go
A vendor/github.com/e3b0c442/warp/.gitignore
A vendor/github.com/e3b0c442/warp/.travis.yml
A vendor/github.com/e3b0c442/warp/CHANGELOG.md
A vendor/github.com/e3b0c442/warp/CONTRIBUTING.md
R vendor/github.com/ugorji/go/codec/{LICENSE => CENSE}
A vendor/github.com/e3b0c442/warp/README.md
A vendor/github.com/e3b0c442/warp/attestation.go
A vendor/github.com/e3b0c442/warp/authentication.go
A vendor/github.com/e3b0c442/warp/authenticator.go
A vendor/github.com/e3b0c442/warp/common.go
A vendor/github.com/e3b0c442/warp/cose.go
A vendor/github.com/e3b0c442/warp/creation.go
A vendor/github.com/e3b0c442/warp/credential.go
A vendor/github.com/e3b0c442/warp/error.go
A vendor/github.com/e3b0c442/warp/extensions.go
A vendor/github.com/e3b0c442/warp/go.mod
A vendor/github.com/e3b0c442/warp/go.sum
A vendor/github.com/e3b0c442/warp/option.go
A vendor/github.com/e3b0c442/warp/parameters.go
A vendor/github.com/e3b0c442/warp/registration.go
A vendor/github.com/e3b0c442/warp/request.go
A vendor/github.com/e3b0c442/warp/response.go
A vendor/github.com/e3b0c442/warp/structures.go
A vendor/github.com/e3b0c442/warp/validator.go
A vendor/github.com/e3b0c442/warp/warp.go
A vendor/github.com/fxamacker/cbor/.gitignore
A vendor/github.com/fxamacker/cbor/.travis.yml
A vendor/github.com/fxamacker/cbor/CBOR_BENCHMARKS.md
A vendor/github.com/fxamacker/cbor/CBOR_GOLANG.md
A vendor/github.com/fxamacker/cbor/CODE_OF_CONDUCT.md
A vendor/github.com/fxamacker/cbor/CONTRIBUTING.md
R vendor/github.com/mitchellh/{mapstructure/LICENSE => cbor/LICENSE}
A vendor/github.com/fxamacker/cbor/README.md
A vendor/github.com/fxamacker/cbor/cache.go
A vendor/github.com/fxamacker/cbor/decode.go
A vendor/github.com/fxamacker/cbor/doc.go
A vendor/github.com/fxamacker/cbor/encode.go
A vendor/github.com/fxamacker/cbor/go.mod
A vendor/github.com/fxamacker/cbor/go.sum
A vendor/github.com/fxamacker/cbor/stream.go
A vendor/github.com/fxamacker/cbor/structfields.go
A vendor/github.com/fxamacker/cbor/valid.go
D vendor/github.com/google/certificate-transparency-go/.gitignore
D vendor/github.com/google/certificate-transparency-go/.travis.yml
D vendor/github.com/google/certificate-transparency-go/AUTHORS
D vendor/github.com/google/certificate-transparency-go/CHANGELOG.md
D vendor/github.com/google/certificate-transparency-go/CONTRIBUTING.md
D vendor/github.com/google/certificate-transparency-go/CONTRIBUTORS
D vendor/github.com/google/certificate-transparency-go/LICENSE
D vendor/github.com/google/certificate-transparency-go/README.md
D vendor/github.com/google/certificate-transparency-go/asn1/asn1.go
D vendor/github.com/google/certificate-transparency-go/asn1/common.go
D vendor/github.com/google/certificate-transparency-go/asn1/marshal.go
D vendor/github.com/google/certificate-transparency-go/cloudbuild_tag.yaml
D vendor/github.com/google/certificate-transparency-go/gometalinter.json
D vendor/github.com/google/certificate-transparency-go/serialization.go
D vendor/github.com/google/certificate-transparency-go/signatures.go
D vendor/github.com/google/certificate-transparency-go/tls/signature.go
D vendor/github.com/google/certificate-transparency-go/tls/tls.go
D vendor/github.com/google/certificate-transparency-go/tls/types.go
D vendor/github.com/google/certificate-transparency-go/types.go
D vendor/github.com/google/certificate-transparency-go/x509/cert_pool.go
D vendor/github.com/google/certificate-transparency-go/x509/curves.go
D vendor/github.com/google/certificate-transparency-go/x509/error.go
D vendor/github.com/google/certificate-transparency-go/x509/errors.go
D vendor/github.com/google/certificate-transparency-go/x509/names.go
D vendor/github.com/google/certificate-transparency-go/x509/nilref_nil_darwin.go
D vendor/github.com/google/certificate-transparency-go/x509/nilref_zero_darwin.go
D vendor/github.com/google/certificate-transparency-go/x509/pem_decrypt.go
D vendor/github.com/google/certificate-transparency-go/x509/pkcs1.go
D vendor/github.com/google/certificate-transparency-go/x509/pkcs8.go
D vendor/github.com/google/certificate-transparency-go/x509/pkix/pkix.go
D vendor/github.com/google/certificate-transparency-go/x509/ptr_sysptr_windows.go
D vendor/github.com/google/certificate-transparency-go/x509/ptr_uint_windows.go
D vendor/github.com/google/certificate-transparency-go/x509/revoked.go
D vendor/github.com/google/certificate-transparency-go/x509/root.go
D vendor/github.com/google/certificate-transparency-go/x509/root_bsd.go
D vendor/github.com/google/certificate-transparency-go/x509/root_cgo_darwin.go
D vendor/github.com/google/certificate-transparency-go/x509/root_darwin.go
D vendor/github.com/google/certificate-transparency-go/x509/root_darwin_armx.go
D vendor/github.com/google/certificate-transparency-go/x509/root_linux.go
D vendor/github.com/google/certificate-transparency-go/x509/root_nacl.go
D vendor/github.com/google/certificate-transparency-go/x509/root_nocgo_darwin.go
D vendor/github.com/google/certificate-transparency-go/x509/root_plan9.go
D vendor/github.com/google/certificate-transparency-go/x509/root_solaris.go
D vendor/github.com/google/certificate-transparency-go/x509/root_unix.go
D vendor/github.com/google/certificate-transparency-go/x509/root_windows.go
D vendor/github.com/google/certificate-transparency-go/x509/rpki.go
D vendor/github.com/google/certificate-transparency-go/x509/sec1.go
D vendor/github.com/google/certificate-transparency-go/x509/test-dir.crt
D vendor/github.com/google/certificate-transparency-go/x509/test-file.crt
D vendor/github.com/google/certificate-transparency-go/x509/verify.go
D vendor/github.com/google/certificate-transparency-go/x509/x509.go
D vendor/github.com/mitchellh/mapstructure/.travis.yml
D vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
D vendor/github.com/mitchellh/mapstructure/README.md
D vendor/github.com/mitchellh/mapstructure/decode_hooks.go
D vendor/github.com/mitchellh/mapstructure/error.go
D vendor/github.com/mitchellh/mapstructure/go.mod
D vendor/github.com/mitchellh/mapstructure/mapstructure.go
D vendor/github.com/satori/go.uuid/.travis.yml
D vendor/github.com/satori/go.uuid/LICENSE
D vendor/github.com/satori/go.uuid/README.md
D vendor/github.com/satori/go.uuid/codec.go
D vendor/github.com/satori/go.uuid/generator.go
D vendor/github.com/satori/go.uuid/sql.go
D vendor/github.com/satori/go.uuid/uuid.go
A vendor/github.com/sirupsen/logrus/.golangci.yml
M vendor/github.com/sirupsen/logrus/.travis.yml
M vendor/github.com/sirupsen/logrus/README.md
M vendor/github.com/sirupsen/logrus/entry.go
M vendor/github.com/sirupsen/logrus/exported.go
M vendor/github.com/sirupsen/logrus/go.mod
M vendor/github.com/sirupsen/logrus/go.sum
M vendor/github.com/sirupsen/logrus/json_formatter.go
M vendor/github.com/sirupsen/logrus/logger.go
M vendor/github.com/sirupsen/logrus/logrus.go
M vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
A vendor/github.com/sirupsen/logrus/terminal_check_js.go
M vendor/github.com/sirupsen/logrus/terminal_check_unix.go
M vendor/github.com/sirupsen/logrus/text_formatter.go
M vendor/github.com/sirupsen/logrus/writer.go
D vendor/github.com/ugorji/go/codec/0_importpath.go
D vendor/github.com/ugorji/go/codec/binc.go
D vendor/github.com/ugorji/go/codec/build.sh
D vendor/github.com/ugorji/go/codec/cbor.go
D vendor/github.com/ugorji/go/codec/codecgen.go
D vendor/github.com/ugorji/go/codec/decode.go
D vendor/github.com/ugorji/go/codec/doc.go
D vendor/github.com/ugorji/go/codec/encode.go
D vendor/github.com/ugorji/go/codec/fast-path.generated.go
D vendor/github.com/ugorji/go/codec/fast-path.go.tmpl
D vendor/github.com/ugorji/go/codec/fast-path.not.go
D vendor/github.com/ugorji/go/codec/float.go
D vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl
D vendor/github.com/ugorji/go/codec/gen-dec-map.go.tmpl
D vendor/github.com/ugorji/go/codec/gen-enc-chan.go.tmpl
D vendor/github.com/ugorji/go/codec/gen-helper.generated.go
D vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl
D vendor/github.com/ugorji/go/codec/gen.generated.go
D vendor/github.com/ugorji/go/codec/gen.go
D vendor/github.com/ugorji/go/codec/go.mod
D vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go
D vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go
D vendor/github.com/ugorji/go/codec/goversion_fmt_time_gte_go15.go
D vendor/github.com/ugorji/go/codec/goversion_fmt_time_lt_go15.go
D vendor/github.com/ugorji/go/codec/goversion_makemap_gte_go19.go
D vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go19.go
D vendor/github.com/ugorji/go/codec/goversion_maprange_gte_go112.go
D vendor/github.com/ugorji/go/codec/goversion_maprange_lt_go112.go
D vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go
D vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go
D vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go
D vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go
D vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go
D vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go
D vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go
D vendor/github.com/ugorji/go/codec/helper.go
D vendor/github.com/ugorji/go/codec/helper.s
D vendor/github.com/ugorji/go/codec/helper_internal.go
D vendor/github.com/ugorji/go/codec/helper_not_unsafe.go
D vendor/github.com/ugorji/go/codec/helper_unsafe.go
D vendor/github.com/ugorji/go/codec/json.go
D vendor/github.com/ugorji/go/codec/mammoth-test.go.tmpl
D vendor/github.com/ugorji/go/codec/mammoth2-test.go.tmpl
D vendor/github.com/ugorji/go/codec/msgpack.go
D vendor/github.com/ugorji/go/codec/prebuild.go
D vendor/github.com/ugorji/go/codec/reader.go
D vendor/github.com/ugorji/go/codec/register_ext.go
D vendor/github.com/ugorji/go/codec/rpc.go
D vendor/github.com/ugorji/go/codec/simple.go
D vendor/github.com/ugorji/go/codec/sort-slice.generated.go
D vendor/github.com/ugorji/go/codec/sort-slice.go.tmpl
D vendor/github.com/ugorji/go/codec/test-cbor-goldens.json
D vendor/github.com/ugorji/go/codec/test.py
D vendor/github.com/ugorji/go/codec/writer.go
A vendor/github.com/x448/float16/.travis.yml
A vendor/github.com/x448/float16/LICENSE
A vendor/github.com/x448/float16/README.md
A vendor/github.com/x448/float16/float16.go
A vendor/github.com/x448/float16/go.mod
M vendor/github.com/yuin/goldmark/extension/typographer.go
M vendor/github.com/yuin/goldmark/parser/list.go
M vendor/github.com/yuin/goldmark/util/util.go
M vendor/github.com/yuin/goldmark/util/util_safe.go
D vendor/golang.org/x/crypto/cryptobyte/asn1.go
D vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go
D vendor/golang.org/x/crypto/cryptobyte/builder.go
D vendor/golang.org/x/crypto/cryptobyte/string.go
D vendor/golang.org/x/crypto/ocsp/ocsp.go
D vendor/golang.org/x/crypto/pkcs12/bmp-string.go
D vendor/golang.org/x/crypto/pkcs12/crypto.go
D vendor/golang.org/x/crypto/pkcs12/errors.go
D vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2.go
D vendor/golang.org/x/crypto/pkcs12/mac.go
D vendor/golang.org/x/crypto/pkcs12/pbkdf.go
D vendor/golang.org/x/crypto/pkcs12/pkcs12.go
D vendor/golang.org/x/crypto/pkcs12/safebags.go
M vendor/modules.txt
M extras/cross_compile.sh => extras/cross_compile.sh +0 -0

M go.mod => go.mod +4 -2
@@ 11,9 11,10 @@ require (
	github.com/blevesearch/segment v0.9.0
	github.com/carbocation/interpose v0.0.0-20161206215253-723534742ba3
	github.com/dave/jennifer v1.4.0
	github.com/duo-labs/webauthn v0.0.0-20200131223046-0864f70a0509
	github.com/dustin/go-humanize v1.0.0
	github.com/e3b0c442/warp v0.6.0
	github.com/evanphx/json-patch v4.5.0+incompatible
	github.com/fxamacker/cbor v1.5.1 // indirect
	github.com/golang/protobuf v1.3.5 // indirect
	github.com/golang/snappy v0.0.1
	github.com/gorilla/context v1.1.1


@@ 29,11 30,12 @@ require (
	github.com/restic/chunker v0.3.0
	github.com/robfig/cron v1.2.0
	github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd
	github.com/sirupsen/logrus v1.5.0 // indirect
	github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d
	github.com/unrolled/secure v1.0.7
	github.com/vmihailenco/msgpack v4.0.4+incompatible
	github.com/xeonx/timeago v1.0.0-rc4
	github.com/yuin/goldmark v1.1.25
	github.com/yuin/goldmark v1.1.28
	github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb
	github.com/zpatrick/rbac v0.0.0-20180829190353-d2c4f050cf28
	golang.org/x/crypto v0.0.0-20200406173513-056763e48d71

M go.sum => go.sum +14 -21
@@ 26,7 26,6 @@ a4.io/gluapp v0.0.0-20200221184138-44fb2766d27d h1:mG+tM6bamBDHVxKF6QgdkRwTyFkmd
a4.io/gluapp v0.0.0-20200221184138-44fb2766d27d/go.mod h1:SnPbw2WapvLDMfarcCs/pqYhYUvQqCk5u6TJjni5M3k=
a4.io/gluapp v0.0.0-20200311203905-eb3c48991ada h1:t7D1dBddA0Joo/MKSIj9GJsv0iGerABouNrNP220PVg=
a4.io/gluapp v0.0.0-20200311203905-eb3c48991ada/go.mod h1:A3U6Yc1zqp5Bnsz7PxrlYmbZ4iEN/LBKeuuwaxpLBMY=
a4.io/gluapp v0.0.0-20200319193350-12ed52fbe112/go.mod h1:vRUnOCoU0xprQIH3uvQJG2NnyqJGFmnqBTk528JCEwg=
a4.io/gluapp v0.0.0-20200404171232-054f285d8e63 h1:5pvuqwXXPmxcM2DiT43qOA/0Pnj0Zymq8uyyE/7qMNs=
a4.io/gluapp v0.0.0-20200404171232-054f285d8e63/go.mod h1:vRUnOCoU0xprQIH3uvQJG2NnyqJGFmnqBTk528JCEwg=
a4.io/gluarequire2 v0.0.0-20170611121149-66e0eb2c6a9f h1:mfEWN0Dd2AfIXU5WO5ZfqbFVk63Qz5M/CANs182pm+U=


@@ 78,8 77,6 @@ github.com/aws/aws-sdk-go v1.29.7 h1:mwe1Bls/BsB3hB3I9CtUIWSpe1u3wdPcwdvtD9lkzsU
github.com/aws/aws-sdk-go v1.29.7/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg=
github.com/aws/aws-sdk-go v1.29.22 h1:3WmsCj3C30l6/4f50mPkDZoTPWSvaRCjcVJOWdCJoIE=
github.com/aws/aws-sdk-go v1.29.22/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg=
github.com/aws/aws-sdk-go v1.30.4 h1:dpQgypC3rld2Uuz+/2u+0nbfmmyEWxau6v1hdAlvoc8=
github.com/aws/aws-sdk-go v1.30.4/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go v1.30.7 h1:IaXfqtioP6p9SFAnNfsqdNczbR5UNbYqvcZUSsCAdTY=
github.com/aws/aws-sdk-go v1.30.7/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/blevesearch/segment v0.0.0-20160915185041-762005e7a34f h1:kqbi9lqXLLs+zfWlgo1PIiRQ86n33K1JKotjj4rSYOg=


@@ 95,8 92,6 @@ github.com/cespare/trie v0.0.0-20150610204604-3fe1a95cbba9/go.mod h1:MCsKum/O9rT
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/cloudflare/cfssl v0.0.0-20190726000631-633726f6bcb7 h1:Puu1hUwfps3+1CUzYdAZXijuvLuRMirgiXdf3zsM2Ig=
github.com/cloudflare/cfssl v0.0.0-20190726000631-633726f6bcb7/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
github.com/codegangsta/negroni v1.0.0 h1:+aYywywx4bnKXWvoWtRfJ91vC59NbEhEY03sZjQhbVY=


@@ 128,15 123,13 @@ github.com/dave/jennifer v1.4.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhr
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/duo-labs/webauthn v0.0.0-20200131223046-0864f70a0509 h1:XlqpA/EJNuSPkp6/yl2fCXcsQ/y5uw4GKkVBYmebdnE=
github.com/duo-labs/webauthn v0.0.0-20200131223046-0864f70a0509/go.mod h1:lLEqCfy8LnwEbRr1SrxujNtHadF3cEGY7MmR3vo0s3A=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/e3b0c442/warp v0.6.0 h1:2GSXT7T/YN7WgYQbjMCHKHo+tDLFJIPopM7Kd8egOQI=
github.com/e3b0c442/warp v0.6.0/go.mod h1:F7cBsflowLSoMt9xwSqoh9f7YwLJEGwkT8In9wp/Rmo=
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712 h1:aaQcKT9WumO6JEJcRyTqFVq4XUZiUcKR2/GI31TOcz8=
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=


@@ 153,6 146,10 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjr
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fxamacker/cbor v1.5.0 h1:idAiyeNSq/jeG9FPbCLVZLFJjsxP+g40a3UrXFapumw=
github.com/fxamacker/cbor v1.5.0/go.mod h1:UjdWSysJckWsChYy9I5zMbkGvK4xXDR+LmDb8kPGYgA=
github.com/fxamacker/cbor v1.5.1 h1:XjQWBgdmQyqimslUh5r4tUGmoqzHmBFQOImkWGi2awg=
github.com/fxamacker/cbor v1.5.1/go.mod h1:3aPGItF174ni7dDzd6JZ206H8cmr4GDNBGpPa971zsU=
github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=


@@ 183,8 180,6 @@ github.com/gomarkdown/markdown v0.0.0-20181104084050-d1d0edeb5d85/go.mod h1:gmFA
github.com/gomarkdown/markdown v0.0.0-20200127000047-1813ea067497/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
github.com/goods/httpbuf v0.0.0-20120503183857-5709e9bb814c h1:kES4WSo15F5Rejf0L5d6kJzZhDRs/0SEvb39I8H6H7g=
github.com/goods/httpbuf v0.0.0-20120503183857-5709e9bb814c/go.mod h1:cHMBumiwaaRxRQ6NT8sU3zQSkXbYaPjbBcXa8UgTzAE=
github.com/google/certificate-transparency-go v1.0.21 h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE=
github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=


@@ 219,6 214,7 @@ github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=


@@ 348,8 344,6 @@ github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 h1:7YvPJVmEeFHR1T
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=


@@ 358,6 352,8 @@ github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q=
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
github.com/src-d/go-oniguruma v1.1.0 h1:EG+Nm5n2JqWUaCjtM0NtutPxU7ZN5Tp50GWrrV8bTww=


@@ 384,10 380,6 @@ github.com/toqueteos/trie v1.0.0 h1:8i6pXxNUXNRAqP246iibb7w/pSFquNTQ+uNfriG7vlk=
github.com/toqueteos/trie v1.0.0/go.mod h1:Ywk48QhEqhU1+DwhMkJ2x7eeGxDHiGkAdc9+0DYcbsM=
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ=
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/unrolled/secure v0.0.0-20181022170031-4b6b7cf51606 h1:dU9yXzNi9rl6Mou7+3npdfPyeFPb2+7BHs3zL47bhPY=
github.com/unrolled/secure v0.0.0-20181022170031-4b6b7cf51606/go.mod h1:mnPT77IAdsi/kV7+Es7y+pXALeV3h7G6dQF6mNYjcLA=
github.com/unrolled/secure v0.0.0-20181221173256-0d6b5bb13069 h1:RKeYksgIwGE8zFJTvXI1WWx09QPrGyaVFMy0vpU7j/o=


@@ 406,6 398,9 @@ github.com/vmihailenco/msgpack v4.0.1+incompatible h1:RMF1enSPeKTlXrXdOcqjFUElyw
github.com/vmihailenco/msgpack v4.0.1+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/x448/float16 v0.8.3/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xanzy/ssh-agent v0.2.0 h1:Adglfbi5p9Z0BmK2oKU9nTG+zKfniSfnaMYB+ULd+Ro=
github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8=
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=


@@ 425,6 420,8 @@ github.com/yuin/goldmark v1.1.23 h1:eTodJ8hwEUvwXhb9qxQNuL/q1d+xMQClrXR4mdvV7gs=
github.com/yuin/goldmark v1.1.23/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.25 h1:isv+Q6HQAmmL2Ofcmg8QauBmDPlUUnSoNhEcC940Rds=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.28 h1:3Ksz4BbKZVlaGbkXzHxoazZzASQKsfUuOZPr5CNxnC4=
github.com/yuin/goldmark v1.1.28/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark-highlighting v0.0.0-20191202084645-78f32c8dd6d5 h1:QbH7ca1qtgZHrzvcVAEoiJIwBqrXxMOfHYfwZIniIK0=
github.com/yuin/goldmark-highlighting v0.0.0-20191202084645-78f32c8dd6d5/go.mod h1:4QGn5rJFOASBa2uK4Q2h3BRTyJqRfsAucPFIipSTcaM=
github.com/yuin/goldmark-highlighting v0.0.0-20200218065240-d1af22c1126f h1:5295skDVJn90SXIYI22jOMeR9XbnuN76y/V1m9N8ITQ=


@@ 456,8 453,6 @@ golang.org/x/crypto v0.0.0-20200221170553-0f24fbd83dfb h1:Bg7BRk6M/6/zfhJrglNmi/
golang.org/x/crypto v0.0.0-20200221170553-0f24fbd83dfb/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 h1:QmwruyY+bKbDDL0BaglrbZABEali68eoMFhTZpCjYVA=
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200403201458-baeed622b8d8 h1:fpnn/HnJONpIu6hkXi1u/7rR0NzilgWr4T0JmWkEitk=
golang.org/x/crypto v0.0.0-20200403201458-baeed622b8d8/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71 h1:DOmugCavvUtnUD114C1Wh+UgTgQZ4pMLzXxi1pSt+/Y=
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=


@@ 527,8 522,6 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa h1:mQTN3ECqfsViCNBgq+A40vdwhkGykrrQlYe3mPj6BoU=
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=

M pkg/webauthn/webauthn.go => pkg/webauthn/webauthn.go +226 -150
@@ 3,19 3,19 @@ package webauthn // import "a4.io/blobstash/pkg/webauthn"

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	"a4.io/blobstash/pkg/config"
	"a4.io/blobstash/pkg/session"
	"github.com/duo-labs/webauthn/protocol"
	w "github.com/duo-labs/webauthn/webauthn"
	"github.com/e3b0c442/warp"
	lua "github.com/yuin/gopher-lua"
)



@@ 23,19 23,85 @@ var id = []byte("1")
var name = "admin"
var sessionName = "webauthn"

type credential struct {
	RPID string
	Cred *w.Credential
type rp struct {
	origin string
}

type user struct {
	conf  *config.Config
	creds []w.Credential
func (r rp) EntityID() string {
	u, _ := url.Parse(r.origin)
	return u.Hostname()
}

func (r rp) EntityName() string {
	return r.origin
}

func (r rp) EntityIcon() string {
	return ""
}

func (r rp) Origin() string {
	return r.origin
}

func (u *user) loadAll() ([]*credential, error) {
	allCreds := []*credential{}
	dat, err := ioutil.ReadFile(filepath.Join(u.conf.VarDir(), "webauthn.json"))
type user2 struct {
	conf        *config.Config
	name        string
	id          []byte
	credentials map[string]warp.Credential
}

func (u *user2) EntityID() []byte {
	return u.id
}

func (u *user2) EntityName() string {
	return u.name
}

func (u *user2) EntityDisplayName() string {
	return u.name
}

func (u *user2) EntityIcon() string {
	return ""
}

func (u *user2) Credentials() map[string]warp.Credential {
	return u.credentials
}

type credential2 struct {
	owner warp.User
	Att   *warp.AttestationObject
	RPID  string
}

func (c *credential2) Owner() warp.User {
	return c.owner
}

func (c *credential2) CredentialID() []byte {
	return c.Att.AuthData.AttestedCredentialData.CredentialID
}

func (c *credential2) CredentialPublicKey() []byte {

	return c.Att.AuthData.AttestedCredentialData.CredentialPublicKey
}

func (c *credential2) CredentialSignCount() uint {
	return 0
}

type sessionData struct {
	CreationOptions *warp.PublicKeyCredentialCreationOptions
	RequestOptions  *warp.PublicKeyCredentialRequestOptions
}

func loadAll(conf *config.Config) ([]*credential2, error) {
	allCreds := []*credential2{}
	dat, err := ioutil.ReadFile(filepath.Join(conf.VarDir(), "webauthn.json"))
	switch {
	case err == nil:
		if err := json.Unmarshal(dat, &allCreds); err != nil {


@@ 49,33 115,33 @@ func (u *user) loadAll() ([]*credential, error) {
	}
}

func (u *user) load(rpid string) error {
	u.creds = nil
	allCreds, err := u.loadAll()
func (u *user2) load(rpid string) error {
	u.credentials = map[string]warp.Credential{}
	allCreds, err := loadAll(u.conf)
	if err != nil {
		return err
	}
	fmt.Printf("ALLCREDS=%+v\n", allCreds)
	for _, cred := range allCreds {
		if cred.RPID == rpid {
			u.creds = append(u.creds, *cred.Cred)
			id := base64.RawURLEncoding.EncodeToString(cred.Att.AuthData.AttestedCredentialData.CredentialID)
			u.credentials[id] = cred
		}
	}
	fmt.Printf("ALLCREDS=%+v\n", u.creds)
	return nil
}

// save or update a Webauthn credential in the JSON DB file
func (u *user) save(rpid string, rcred *w.Credential) error {
	allCreds, err := u.loadAll()
func (u *user2) save(rpid string, rcred *credential2) error {
	allCreds, err := loadAll(u.conf)
	if err != nil {
		return err
	}
	newCreds := []*credential{}
	newCreds := []*credential2{}
	var replaced bool
	for _, acred := range allCreds {
		if acred.RPID == rpid && bytes.Equal(acred.Cred.ID, rcred.ID) {
			newCreds = append(newCreds, &credential{rpid, rcred})
		if acred.RPID == rpid && bytes.Equal(acred.Att.AuthData.AttestedCredentialData.CredentialID, rcred.Att.AuthData.AttestedCredentialData.CredentialID) {
			newCreds = append(newCreds, rcred)
			replaced = true
			continue
		}


@@ 84,7 150,7 @@ func (u *user) save(rpid string, rcred *w.Credential) error {
	}

	if !replaced {
		newCreds = append(newCreds, &credential{rpid, rcred})
		newCreds = append(newCreds, rcred)
	}

	js, err := json.Marshal(newCreds)


@@ 97,76 163,56 @@ func (u *user) save(rpid string, rcred *w.Credential) error {
	return nil
}

func (u *user) WebAuthnID() []byte {
	return id
}

func (u *user) WebAuthnName() string {
	return name
}

func (u *user) WebAuthnDisplayName() string {
	return name
}

func (u *user) WebAuthnIcon() string {
	return ""
}

func (u *user) CredentialExcludeList() []protocol.CredentialDescriptor {
	credentialExcludeList := []protocol.CredentialDescriptor{}
	//for _, cred := range u.credentials {
	//	descriptor := protocol.CredentialDescriptor{
	//		Type:         protocol.PublicKeyCredentialType,
	//		CredentialID: cred.ID,
	//	}
	//	credentialExcludeList = append(credentialExcludeList, descriptor)
	//}

	return credentialExcludeList
}

func (u *user) WebAuthnCredentials() []w.Credential {
	return u.creds
}

type WebAuthn struct {
	conf  *config.Config
	sess  *session.Session
	rdata *w.SessionData
	user  *user
	user2 *user2
}

func New(conf *config.Config, s *session.Session) (*WebAuthn, error) {
	return &WebAuthn{
		sess: s,
		conf: conf,
		user: &user{conf, nil},
		user2: &user2{
			conf:        conf,
			id:          id,
			name:        name,
			credentials: map[string]warp.Credential{},
		},
	}, nil
}

func (wa *WebAuthn) BeginRegistration(rw http.ResponseWriter, r *http.Request, origin string) (string, error) {
	web, err := wa.web(origin)
	if err != nil {
		return "", err
func (wa *WebAuthn) findCredential(id []byte) (warp.Credential, error) {
	strID := base64.RawStdEncoding.EncodeToString(id)
	if c, ok := wa.user2.credentials[strID]; ok {
		return c, nil
	}
	return nil, fmt.Errorf("no credential")
}

	registerOptions := func(credCreationOpts *protocol.PublicKeyCredentialCreationOptions) {
func (wa *WebAuthn) BeginRegistration2(rw http.ResponseWriter, r *http.Request, origin string) (string, error) {
	relyingParty := &rp{
		origin: origin,
	}

	if err := wa.user2.load(relyingParty.EntityID()); err != nil {
		return "", err
	}
	options, sessionData, err := web.BeginRegistration(
		wa.user,
		registerOptions,
	)

	opts, err := warp.StartRegistration(relyingParty, wa.user2, warp.Attestation(warp.ConveyanceDirect))
	if err != nil {
		return "", err
	}

	if err := wa.saveSession(rw, r, "registration", sessionData); err != nil {
	sessionData := &sessionData{
		CreationOptions: opts,
	}

	if err := wa.saveSession2(rw, r, "registration", sessionData); err != nil {
		return "", err
	}

	js, err := json.Marshal(options)
	js, err := json.Marshal(opts)
	if err != nil {
		return "", err
	}


@@ 174,34 220,60 @@ func (wa *WebAuthn) BeginRegistration(rw http.ResponseWriter, r *http.Request, o
	return string(js), nil
}

func (wa *WebAuthn) FinishRegistration(rw http.ResponseWriter, r *http.Request, origin, js string) error {
	web, err := wa.web(origin)
	if err != nil {
func (wa *WebAuthn) CredentialFinder(id []byte) (warp.Credential, error) {
	return nil, fmt.Errorf("no creds")
}

func (wa *WebAuthn) FinishRegistration2(rw http.ResponseWriter, r *http.Request, origin, js string) error {
	relyingParty := &rp{
		origin: origin,
	}

	if err := wa.user2.load(relyingParty.EntityID()); err != nil {
		return err
	}

	sessionData, err := wa.getSession(r, "registration")
	fmt.Printf("will GOT SESSION\n\n")
	sessionData, err := wa.getSession2(r, "registration")
	if err != nil {
		panic(err)
		panic(fmt.Errorf("failed to get session: %w", err))
	}

	fmt.Printf("GOT SESSION\n\n")

	cred := warp.AttestationPublicKeyCredential{}
	if err := json.Unmarshal([]byte(js), &cred); err != nil {
		return fmt.Errorf("failed to unmarshal attestation: %w", err)
	}
	fmt.Printf("JS=%s\n\n\n\n", js)
	inputPayload := strings.NewReader(js)
	parsedResponse, err := protocol.ParseCredentialCreationResponseBody(inputPayload)
	fmt.Printf("RESP=%+v\nerr=%v\nuser=%+v\n\n", parsedResponse, err, wa.user)
	ncred, err := web.CreateCredential(wa.user, *sessionData, parsedResponse)

	att, err := warp.FinishRegistration(relyingParty, wa.CredentialFinder, sessionData.CreationOptions, &cred)
	if err != nil {
		return err
		fmt.Printf("finish reg failed: %v\n\n", err)
		for err != nil {
			fmt.Printf("%v", err)
			err = errors.Unwrap(err)
		}
		return fmt.Errorf("failed to finish registration: %w", err)
	}
	fmt.Printf("ncred=%v\n", ncred)
	if err := wa.user.save(web.Config.RPID, ncred); err != nil {
		return err

	fmt.Printf("att=%+v\n\n", att)

	newCred := &credential2{
		RPID:  relyingParty.EntityID(),
		Att:   att,
		owner: wa.user2,
	}

	if err := wa.user2.save(relyingParty.EntityID(), newCred); err != nil {
		panic(err)
	}

	return nil
}

func (wa *WebAuthn) saveSession(rw http.ResponseWriter, r *http.Request, name string, sessionData *w.SessionData) error {
func (wa *WebAuthn) saveSession2(rw http.ResponseWriter, r *http.Request, name string, sessionData *sessionData) error {
	fmt.Printf("WA: %+v\n", wa)
	store, err := wa.sess.Session().Get(r, "webauthn")
	store, err := wa.sess.Session().Get(r, "webauthn2")
	if err != nil {
		return err
	}


@@ 218,118 290,122 @@ func (wa *WebAuthn) saveSession(rw http.ResponseWriter, r *http.Request, name st
	return nil
}

func (wa *WebAuthn) getSession(r *http.Request, name string) (*w.SessionData, error) {
	store, err := wa.sess.Session().Get(r, "webauthn")
func (wa *WebAuthn) getSession2(r *http.Request, name string) (*sessionData, error) {
	store, err := wa.sess.Session().Get(r, "webauthn2")
	if err != nil {
		return nil, err
	}
	sessionData := w.SessionData{}
	sessionData := &sessionData{}
	js := store.Values[name].([]byte)

	if err := json.Unmarshal(js, &sessionData); err != nil {
		return nil, err
	}
	delete(store.Values, name)
	return &sessionData, nil
	return sessionData, nil
}

func (wa *WebAuthn) web(origin string) (*w.WebAuthn, error) {
	u, err := url.Parse(origin)
	if err != nil {
		return nil, err
	}
	rpid := strings.Split(u.Host, ":")[0]
	if rpid == "0.0.0.0" {
		rpid = "localhost"
	}
	u.Path = "/"
	u.Host = strings.Replace(u.Host, "0.0.0.0", "localhost", 1)

	web, err := w.New(&w.Config{
		RPDisplayName: "BlobStash",
		RPID:          rpid,
		RPOrigin:      u.String(),
	})
	if err != nil {
		return nil, err
func (wa *WebAuthn) BeginLogin2(rw http.ResponseWriter, r *http.Request, origin string) (string, error) {
	relyingParty := &rp{
		origin: origin,
	}

	return web, nil
}

func (wa *WebAuthn) BeginLogin(rw http.ResponseWriter, r *http.Request, origin string) (string, error) {
	web, err := wa.web(origin)
	if err != nil {
	if err := wa.user2.load(relyingParty.EntityID()); err != nil {
		return "", err
	}
	if err := wa.user.load(web.Config.RPID); err != nil {
		panic(err)
	}
	options, sessionData, err := web.BeginLogin(wa.user)
	if err != nil {
		return "", err

	opts, err := warp.StartAuthentication(warp.AllowCredentials(
		func(user warp.User) []warp.PublicKeyCredentialDescriptor {
			ds := []warp.PublicKeyCredentialDescriptor{}
			for _, c := range user.Credentials() {
				ds = append(ds, warp.PublicKeyCredentialDescriptor{
					Type: "public-key",
					ID:   c.CredentialID(),
				})
			}
			return ds
		}(wa.user2)),
		warp.RelyingPartyID(relyingParty.EntityID()),
	)
	sessionData := &sessionData{
		RequestOptions: opts,
	}
	if err := wa.saveSession(rw, r, "login", sessionData); err != nil {

	if err := wa.saveSession2(rw, r, "login3", sessionData); err != nil {
		return "", err
	}

	js, err := json.Marshal(options)
	js, err := json.Marshal(opts)
	if err != nil {
		return "", err
	}
	return string(js), nil
}

func (wa *WebAuthn) FinishLogin(rw http.ResponseWriter, r *http.Request, origin, js string) error {
	web, err := wa.web(origin)
	if err != nil {
		return err
func (wa *WebAuthn) FinishLogin2(rw http.ResponseWriter, r *http.Request, origin, js string) error {
	relyingParty := &rp{
		origin: origin,
	}
	sessionData, err := wa.getSession(r, "login")
	if err != nil {

	if err := wa.user2.load(relyingParty.EntityID()); err != nil {
		return err
	}
	inputPayload := strings.NewReader(js)
	parsedResponse, err := protocol.ParseCredentialRequestResponseBody(inputPayload)

	sessionData, err := wa.getSession2(r, "login3")
	if err != nil {
		return err
		panic(err)
	}
	ncred, err := web.ValidateLogin(wa.user, *sessionData, parsedResponse)
	if err != nil {

	cred := warp.AssertionPublicKeyCredential{}
	if err := json.Unmarshal([]byte(js), &cred); err != nil {
		return err
	}
	// FIXME(ts): check the counter, warning, and store the new cred
	if err := wa.user.save(web.Config.RPID, ncred); err != nil {

	_, err = warp.FinishAuthentication(
		relyingParty,
		func(_ []byte) (warp.User, error) {
			return wa.user2, nil
		},
		sessionData.RequestOptions,
		&cred,
	)

	if err != nil {
		return err
	}
	fmt.Printf("NCREDS_TO_SAVE=%+v\n", ncred)

	return nil
}

func (wa *WebAuthn) SetupLua(L *lua.LState, baseURL string, w http.ResponseWriter, r *http.Request) {
	L.PreloadModule("webauthn", func(L *lua.LState) int {
		u, err := url.Parse(baseURL)
		if err != nil {
			panic(err)
		}
		u.Path = ""
		baseURL = u.String()

		mod := L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{
			"registered_credentials": func(L *lua.LState) int {
				web, err := wa.web(baseURL)
				if err != nil {
					panic(err)
				relyingParty := &rp{
					origin: baseURL,
				}

				if err := wa.user.load(web.Config.RPID); err != nil {
				if err := wa.user2.load(relyingParty.EntityID()); err != nil {
					panic(err)
				}

				tbl := L.NewTable()
				if wa.user.creds != nil {
					for _, cred := range wa.user.creds {
						tbl.Append(lua.LString(string(cred.ID)))
					}

				for id, _ := range wa.user2.credentials {
					tbl.Append(lua.LString(id))
				}

				L.Push(tbl)
				return 1
			},
			"begin_registration": func(L *lua.LState) int {
				js, err := wa.BeginRegistration(w, r, baseURL)
				js, err := wa.BeginRegistration2(w, r, baseURL)
				if err != nil {
					panic(err)
				}


@@ 337,14 413,14 @@ func (wa *WebAuthn) SetupLua(L *lua.LState, baseURL string, w http.ResponseWrite
				return 1
			},
			"finish_registration": func(L *lua.LState) int {
				if err := wa.FinishRegistration(w, r, baseURL, L.ToString(1)); err != nil {
				if err := wa.FinishRegistration2(w, r, baseURL, L.ToString(1)); err != nil {
					panic(err)
				}
				L.Push(lua.LNil)
				return 1
			},
			"begin_login": func(L *lua.LState) int {
				js, err := wa.BeginLogin(w, r, baseURL)
				js, err := wa.BeginLogin2(w, r, baseURL)
				if err != nil {
					panic(err)
				}


@@ 353,7 429,7 @@ func (wa *WebAuthn) SetupLua(L *lua.LState, baseURL string, w http.ResponseWrite
			},
			"finish_login": func(L *lua.LState) int {
				js := L.ToString(1)
				if err := wa.FinishLogin(w, r, baseURL, js); err != nil {
				if err := wa.FinishLogin2(w, r, baseURL, js); err != nil {
					panic(err)
				}
				L.Push(lua.LNil)

D vendor/github.com/cloudflare/cfssl/LICENSE => vendor/github.com/cloudflare/cfssl/LICENSE +0 -24
@@ 1,24 0,0 @@
Copyright (c) 2014 CloudFlare Inc.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

D vendor/github.com/cloudflare/cfssl/crypto/pkcs7/pkcs7.go => vendor/github.com/cloudflare/cfssl/crypto/pkcs7/pkcs7.go +0 -188
@@ 1,188 0,0 @@
// Package pkcs7 implements the subset of the CMS PKCS #7 datatype that is typically
// used to package certificates and CRLs.  Using openssl, every certificate converted
// to PKCS #7 format from another encoding such as PEM conforms to this implementation.
// reference: https://www.openssl.org/docs/man1.1.0/apps/crl2pkcs7.html
//
//			PKCS #7 Data type, reference: https://tools.ietf.org/html/rfc2315
//
// The full pkcs#7 cryptographic message syntax allows for cryptographic enhancements,
// for example data can be encrypted and signed and then packaged through pkcs#7 to be
// sent over a network and then verified and decrypted.  It is asn1, and the type of
// PKCS #7 ContentInfo, which comprises the PKCS #7 structure, is:
//
//			ContentInfo ::= SEQUENCE {
//				contentType ContentType,
//				content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL
//			}
//
// There are 6 possible ContentTypes, data, signedData, envelopedData,
// signedAndEnvelopedData, digestedData, and encryptedData.  Here signedData, Data, and encrypted
// Data are implemented, as the degenerate case of signedData without a signature is the typical
// format for transferring certificates and CRLS, and Data and encryptedData are used in PKCS #12
// formats.
// The ContentType signedData has the form:
//
//
//			signedData ::= SEQUENCE {
//				version Version,
//				digestAlgorithms DigestAlgorithmIdentifiers,
//				contentInfo ContentInfo,
//				certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL
//				crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
//				signerInfos SignerInfos
//			}
//
// As of yet signerInfos and digestAlgorithms are not parsed, as they are not relevant to
// this system's use of PKCS #7 data.  Version is an integer type, note that PKCS #7 is
// recursive, this second layer of ContentInfo is similar ignored for our degenerate
// usage.  The ExtendedCertificatesAndCertificates type consists of a sequence of choices
// between PKCS #6 extended certificates and x509 certificates.  Any sequence consisting
// of any number of extended certificates is not yet supported in this implementation.
//
// The ContentType Data is simply a raw octet string and is parsed directly into a Go []byte slice.
//
// The ContentType encryptedData is the most complicated and its form can be gathered by
// the go type below.  It essentially contains a raw octet string of encrypted data and an
// algorithm identifier for use in decrypting this data.
package pkcs7

import (
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"errors"

	cferr "github.com/cloudflare/cfssl/errors"
)

// Types used for asn1 Unmarshaling.

type signedData struct {
	Version          int
	DigestAlgorithms asn1.RawValue
	ContentInfo      asn1.RawValue
	Certificates     asn1.RawValue `asn1:"optional" asn1:"tag:0"`
	Crls             asn1.RawValue `asn1:"optional"`
	SignerInfos      asn1.RawValue
}

type initPKCS7 struct {
	Raw         asn1.RawContent
	ContentType asn1.ObjectIdentifier
	Content     asn1.RawValue `asn1:"tag:0,explicit,optional"`
}

// Object identifier strings of the three implemented PKCS7 types.
const (
	ObjIDData          = "1.2.840.113549.1.7.1"
	ObjIDSignedData    = "1.2.840.113549.1.7.2"
	ObjIDEncryptedData = "1.2.840.113549.1.7.6"
)

// PKCS7 represents the ASN1 PKCS #7 Content type.  It contains one of three
// possible types of Content objects, as denoted by the object identifier in
// the ContentInfo field, the other two being nil.  SignedData
// is the degenerate SignedData Content info without signature used
// to hold certificates and crls.  Data is raw bytes, and EncryptedData
// is as defined in PKCS #7 standard.
type PKCS7 struct {
	Raw         asn1.RawContent
	ContentInfo string
	Content     Content
}

// Content implements three of the six possible PKCS7 data types.  Only one is non-nil.
type Content struct {
	Data          []byte
	SignedData    SignedData
	EncryptedData EncryptedData
}

// SignedData defines the typical carrier of certificates and crls.
type SignedData struct {
	Raw          asn1.RawContent
	Version      int
	Certificates []*x509.Certificate
	Crl          *pkix.CertificateList
}

// Data contains raw bytes.  Used as a subtype in PKCS12.
type Data struct {
	Bytes []byte
}

// EncryptedData contains encrypted data.  Used as a subtype in PKCS12.
type EncryptedData struct {
	Raw                  asn1.RawContent
	Version              int
	EncryptedContentInfo EncryptedContentInfo
}

// EncryptedContentInfo is a subtype of PKCS7EncryptedData.
type EncryptedContentInfo struct {
	Raw                        asn1.RawContent
	ContentType                asn1.ObjectIdentifier
	ContentEncryptionAlgorithm pkix.AlgorithmIdentifier
	EncryptedContent           []byte `asn1:"tag:0,optional"`
}

// ParsePKCS7 attempts to parse the DER encoded bytes of a
// PKCS7 structure.
func ParsePKCS7(raw []byte) (msg *PKCS7, err error) {

	var pkcs7 initPKCS7
	_, err = asn1.Unmarshal(raw, &pkcs7)
	if err != nil {
		return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err)
	}

	msg = new(PKCS7)
	msg.Raw = pkcs7.Raw
	msg.ContentInfo = pkcs7.ContentType.String()
	switch {
	case msg.ContentInfo == ObjIDData:
		msg.ContentInfo = "Data"
		_, err = asn1.Unmarshal(pkcs7.Content.Bytes, &msg.Content.Data)
		if err != nil {
			return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err)
		}
	case msg.ContentInfo == ObjIDSignedData:
		msg.ContentInfo = "SignedData"
		var signedData signedData
		_, err = asn1.Unmarshal(pkcs7.Content.Bytes, &signedData)
		if err != nil {
			return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err)
		}
		if len(signedData.Certificates.Bytes) != 0 {
			msg.Content.SignedData.Certificates, err = x509.ParseCertificates(signedData.Certificates.Bytes)
			if err != nil {
				return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err)
			}
		}
		if len(signedData.Crls.Bytes) != 0 {
			msg.Content.SignedData.Crl, err = x509.ParseDERCRL(signedData.Crls.Bytes)
			if err != nil {
				return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err)
			}
		}
		msg.Content.SignedData.Version = signedData.Version
		msg.Content.SignedData.Raw = pkcs7.Content.Bytes
	case msg.ContentInfo == ObjIDEncryptedData:
		msg.ContentInfo = "EncryptedData"
		var encryptedData EncryptedData
		_, err = asn1.Unmarshal(pkcs7.Content.Bytes, &encryptedData)
		if err != nil {
			return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err)
		}
		if encryptedData.Version != 0 {
			return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("Only support for PKCS #7 encryptedData version 0"))
		}
		msg.Content.EncryptedData = encryptedData

	default:
		return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("Attempt to parse PKCS# 7 Content not of type data, signed data or encrypted data"))
	}

	return msg, nil

}

D vendor/github.com/cloudflare/cfssl/errors/doc.go => vendor/github.com/cloudflare/cfssl/errors/doc.go +0 -46
@@ 1,46 0,0 @@
/*
Package errors provides error types returned in CF SSL.

1. Type Error is intended for errors produced by CF SSL packages.
It formats to a json object that consists of an error message and a 4-digit code for error reasoning.

Example: {"code":1002, "message": "Failed to decode certificate"}

The index of codes are listed below:
	1XXX: CertificateError
	    1000: Unknown
	    1001: ReadFailed
	    1002: DecodeFailed
	    1003: ParseFailed
	    1100: SelfSigned
	    12XX: VerifyFailed
	        121X: CertificateInvalid
	            1210: NotAuthorizedToSign
	            1211: Expired
	            1212: CANotAuthorizedForThisName
	            1213: TooManyIntermediates
	            1214: IncompatibleUsage
	        1220: UnknownAuthority
	2XXX: PrivatekeyError
	    2000: Unknown
	    2001: ReadFailed
	    2002: DecodeFailed
	    2003: ParseFailed
	    2100: Encrypted
	    2200: NotRSA
	    2300: KeyMismatch
	    2400: GenerationFailed
	    2500: Unavailable
	3XXX: IntermediatesError
	4XXX: RootError
	5XXX: PolicyError
	    5100: NoKeyUsages
	    5200: InvalidPolicy
	    5300: InvalidRequest
	    5400: UnknownProfile
	    6XXX: DialError

2. Type HttpError is intended for CF SSL API to consume. It contains a HTTP status code that will be read and returned
by the API server.
*/
package errors

D vendor/github.com/cloudflare/cfssl/errors/error.go => vendor/github.com/cloudflare/cfssl/errors/error.go +0 -438
@@ 1,438 0,0 @@
package errors

import (
	"crypto/x509"
	"encoding/json"
	"fmt"
)

// Error is the error type usually returned by functions in CF SSL package.
// It contains a 4-digit error code where the most significant digit
// describes the category where the error occurred and the rest 3 digits
// describe the specific error reason.
type Error struct {
	ErrorCode int    `json:"code"`
	Message   string `json:"message"`
}

// Category is the most significant digit of the error code.
type Category int

// Reason is the last 3 digits of the error code.
type Reason int

const (
	// Success indicates no error occurred.
	Success Category = 1000 * iota // 0XXX

	// CertificateError indicates a fault in a certificate.
	CertificateError // 1XXX

	// PrivateKeyError indicates a fault in a private key.
	PrivateKeyError // 2XXX

	// IntermediatesError indicates a fault in an intermediate.
	IntermediatesError // 3XXX

	// RootError indicates a fault in a root.
	RootError // 4XXX

	// PolicyError indicates an error arising from a malformed or
	// non-existent policy, or a breach of policy.
	PolicyError // 5XXX

	// DialError indicates a network fault.
	DialError // 6XXX

	// APIClientError indicates a problem with the API client.
	APIClientError // 7XXX

	// OCSPError indicates a problem with OCSP signing
	OCSPError // 8XXX

	// CSRError indicates a problem with CSR parsing
	CSRError // 9XXX

	// CTError indicates a problem with the certificate transparency process
	CTError // 10XXX

	// CertStoreError indicates a problem with the certificate store
	CertStoreError // 11XXX
)

// None is a non-specified error.
const (
	None Reason = iota
)

// Warning code for a success
const (
	BundleExpiringBit      int = 1 << iota // 0x01
	BundleNotUbiquitousBit                 // 0x02
)

// Parsing errors
const (
	Unknown      Reason = iota // X000
	ReadFailed                 // X001
	DecodeFailed               // X002
	ParseFailed                // X003
)

// The following represent certificate non-parsing errors, and must be
// specified along with CertificateError.
const (
	// SelfSigned indicates that a certificate is self-signed and
	// cannot be used in the manner being attempted.
	SelfSigned Reason = 100 * (iota + 1) // Code 11XX

	// VerifyFailed is an X.509 verification failure. The least two
	// significant digits of 12XX is determined as the actual x509
	// error is examined.
	VerifyFailed // Code 12XX

	// BadRequest indicates that the certificate request is invalid.
	BadRequest // Code 13XX

	// MissingSerial indicates that the profile specified
	// 'ClientProvidesSerialNumbers', but the SignRequest did not include a serial
	// number.
	MissingSerial // Code 14XX
)

const (
	certificateInvalid = 10 * (iota + 1) //121X
	unknownAuthority                     //122x
)

// The following represent private-key non-parsing errors, and must be
// specified with PrivateKeyError.
const (
	// Encrypted indicates that the private key is a PKCS #8 encrypted
	// private key. At this time, CFSSL does not support decrypting
	// these keys.
	Encrypted Reason = 100 * (iota + 1) //21XX

	// NotRSAOrECC indicates that they key is not an RSA or ECC
	// private key; these are the only two private key types supported
	// at this time by CFSSL.
	NotRSAOrECC //22XX

	// KeyMismatch indicates that the private key does not match
	// the public key or certificate being presented with the key.
	KeyMismatch //23XX

	// GenerationFailed indicates that a private key could not
	// be generated.
	GenerationFailed //24XX

	// Unavailable indicates that a private key mechanism (such as
	// PKCS #11) was requested but support for that mechanism is
	// not available.
	Unavailable
)

// The following are policy-related non-parsing errors, and must be
// specified along with PolicyError.
const (
	// NoKeyUsages indicates that the profile does not permit any
	// key usages for the certificate.
	NoKeyUsages Reason = 100 * (iota + 1) // 51XX

	// InvalidPolicy indicates that policy being requested is not
	// a valid policy or does not exist.
	InvalidPolicy // 52XX

	// InvalidRequest indicates a certificate request violated the
	// constraints of the policy being applied to the request.
	InvalidRequest // 53XX

	// UnknownProfile indicates that the profile does not exist.
	UnknownProfile // 54XX

	UnmatchedWhitelist // 55xx
)

// The following are API client related errors, and should be
// specified with APIClientError.
const (
	// AuthenticationFailure occurs when the client is unable
	// to obtain an authentication token for the request.
	AuthenticationFailure Reason = 100 * (iota + 1)

	// JSONError wraps an encoding/json error.
	JSONError

	// IOError wraps an io/ioutil error.
	IOError

	// ClientHTTPError wraps a net/http error.
	ClientHTTPError

	// ServerRequestFailed covers any other failures from the API
	// client.
	ServerRequestFailed
)

// The following are OCSP related errors, and should be
// specified with OCSPError
const (
	// IssuerMismatch ocurs when the certificate in the OCSP signing
	// request was not issued by the CA that this responder responds for.
	IssuerMismatch Reason = 100 * (iota + 1) // 81XX

	// InvalidStatus occurs when the OCSP signing requests includes an
	// invalid value for the certificate status.
	InvalidStatus
)

// Certificate transparency related errors specified with CTError
const (
	// PrecertSubmissionFailed occurs when submitting a precertificate to
	// a log server fails
	PrecertSubmissionFailed = 100 * (iota + 1)
	// CTClientConstructionFailed occurs when the construction of a new
	// github.com/google/certificate-transparency client fails.
	CTClientConstructionFailed
	// PrecertMissingPoison occurs when a precert is passed to SignFromPrecert
	// and is missing the CT poison extension.
	PrecertMissingPoison
	// PrecertInvalidPoison occurs when a precert is passed to SignFromPrecert
	// and has a invalid CT poison extension value or the extension is not
	// critical.
	PrecertInvalidPoison
)

// Certificate persistence related errors specified with CertStoreError
const (
	// InsertionFailed occurs when a SQL insert query failes to complete.
	InsertionFailed = 100 * (iota + 1)
	// RecordNotFound occurs when a SQL query targeting on one unique
	// record failes to update the specified row in the table.
	RecordNotFound
)

// The error interface implementation, which formats to a JSON object string.
func (e *Error) Error() string {
	marshaled, err := json.Marshal(e)
	if err != nil {
		panic(err)
	}
	return string(marshaled)

}

// New returns an error that contains  an error code and message derived from
// the given category, reason. Currently, to avoid confusion, it is not
// allowed to create an error of category Success
func New(category Category, reason Reason) *Error {
	errorCode := int(category) + int(reason)
	var msg string
	switch category {
	case OCSPError:
		switch reason {
		case ReadFailed:
			msg = "No certificate provided"
		case IssuerMismatch:
			msg = "Certificate not issued by this issuer"
		case InvalidStatus:
			msg = "Invalid revocation status"
		}
	case CertificateError:
		switch reason {
		case Unknown:
			msg = "Unknown certificate error"
		case ReadFailed:
			msg = "Failed to read certificate"
		case DecodeFailed:
			msg = "Failed to decode certificate"
		case ParseFailed:
			msg = "Failed to parse certificate"
		case SelfSigned:
			msg = "Certificate is self signed"
		case VerifyFailed:
			msg = "Unable to verify certificate"
		case BadRequest:
			msg = "Invalid certificate request"
		case MissingSerial:
			msg = "Missing serial number in request"
		default:
			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category CertificateError.",
				reason))

		}
	case PrivateKeyError:
		switch reason {
		case Unknown:
			msg = "Unknown private key error"
		case ReadFailed:
			msg = "Failed to read private key"
		case DecodeFailed:
			msg = "Failed to decode private key"
		case ParseFailed:
			msg = "Failed to parse private key"
		case Encrypted:
			msg = "Private key is encrypted."
		case NotRSAOrECC:
			msg = "Private key algorithm is not RSA or ECC"
		case KeyMismatch:
			msg = "Private key does not match public key"
		case GenerationFailed:
			msg = "Failed to new private key"
		case Unavailable:
			msg = "Private key is unavailable"
		default:
			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category PrivateKeyError.",
				reason))
		}
	case IntermediatesError:
		switch reason {
		case Unknown:
			msg = "Unknown intermediate certificate error"
		case ReadFailed:
			msg = "Failed to read intermediate certificate"
		case DecodeFailed:
			msg = "Failed to decode intermediate certificate"
		case ParseFailed:
			msg = "Failed to parse intermediate certificate"
		default:
			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category IntermediatesError.",
				reason))
		}
	case RootError:
		switch reason {
		case Unknown:
			msg = "Unknown root certificate error"
		case ReadFailed:
			msg = "Failed to read root certificate"
		case DecodeFailed:
			msg = "Failed to decode root certificate"
		case ParseFailed:
			msg = "Failed to parse root certificate"
		default:
			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category RootError.",
				reason))
		}
	case PolicyError:
		switch reason {
		case Unknown:
			msg = "Unknown policy error"
		case NoKeyUsages:
			msg = "Invalid policy: no key usage available"
		case InvalidPolicy:
			msg = "Invalid or unknown policy"
		case InvalidRequest:
			msg = "Policy violation request"
		case UnknownProfile:
			msg = "Unknown policy profile"
		case UnmatchedWhitelist:
			msg = "Request does not match policy whitelist"
		default:
			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category PolicyError.",
				reason))
		}
	case DialError:
		switch reason {
		case Unknown:
			msg = "Failed to dial remote server"
		default:
			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category DialError.",
				reason))
		}
	case APIClientError:
		switch reason {
		case AuthenticationFailure:
			msg = "API client authentication failure"
		case JSONError:
			msg = "API client JSON config error"
		case ClientHTTPError:
			msg = "API client HTTP error"
		case IOError:
			msg = "API client IO error"
		case ServerRequestFailed:
			msg = "API client error: Server request failed"
		default:
			panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category APIClientError.",
				reason))
		}
	case CSRError:
		switch reason {
		case Unknown:
			msg = "CSR parsing failed due to unknown error"
		case ReadFailed:
			msg = "CSR file read failed"
		case ParseFailed:
			msg = "CSR Parsing failed"
		case DecodeFailed:
			msg = "CSR Decode failed"
		case BadRequest:
			msg = "CSR Bad request"
		default:
			panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category APIClientError.", reason))
		}
	case CTError:
		switch reason {
		case Unknown:
			msg = "Certificate transparency parsing failed due to unknown error"
		case PrecertSubmissionFailed:
			msg = "Certificate transparency precertificate submission failed"
		case PrecertMissingPoison:
			msg = "Precertificate is missing CT poison extension"
		case PrecertInvalidPoison:
			msg = "Precertificate contains an invalid CT poison extension"
		default:
			panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category CTError.", reason))
		}
	case CertStoreError:
		switch reason {
		case Unknown:
			msg = "Certificate store action failed due to unknown error"
		default:
			panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category CertStoreError.", reason))
		}

	default:
		panic(fmt.Sprintf("Unsupported CFSSL error type: %d.",
			category))
	}
	return &Error{ErrorCode: errorCode, Message: msg}
}

// Wrap returns an error that contains the given error and an error code derived from
// the given category, reason and the error. Currently, to avoid confusion, it is not
// allowed to create an error of category Success
func Wrap(category Category, reason Reason, err error) *Error {
	errorCode := int(category) + int(reason)
	if err == nil {
		panic("Wrap needs a supplied error to initialize.")
	}

	// do not double wrap a error
	switch err.(type) {
	case *Error:
		panic("Unable to wrap a wrapped error.")
	}

	switch category {
	case CertificateError:
		// given VerifyFailed , report the status with more detailed status code
		// for some certificate errors we care.
		if reason == VerifyFailed {
			switch errorType := err.(type) {
			case x509.CertificateInvalidError:
				errorCode += certificateInvalid + int(errorType.Reason)
			case x509.UnknownAuthorityError:
				errorCode += unknownAuthority
			}
		}
	case PrivateKeyError, IntermediatesError, RootError, PolicyError, DialError,
		APIClientError, CSRError, CTError, CertStoreError, OCSPError:
	// no-op, just use the error
	default:
		panic(fmt.Sprintf("Unsupported CFSSL error type: %d.",
			category))
	}

	return &Error{ErrorCode: errorCode, Message: err.Error()}

}

D vendor/github.com/cloudflare/cfssl/errors/http.go => vendor/github.com/cloudflare/cfssl/errors/http.go +0 -47
@@ 1,47 0,0 @@
package errors

import (
	"errors"
	"net/http"
)

// HTTPError is an augmented error with a HTTP status code.
type HTTPError struct {
	StatusCode int
	error
}

// Error implements the error interface.
func (e *HTTPError) Error() string {
	return e.error.Error()
}

// NewMethodNotAllowed returns an appropriate error in the case that
// an HTTP client uses an invalid method (i.e. a GET in place of a POST)
// on an API endpoint.
func NewMethodNotAllowed(method string) *HTTPError {
	return &HTTPError{http.StatusMethodNotAllowed, errors.New(`Method is not allowed:"` + method + `"`)}
}

// NewBadRequest creates a HttpError with the given error and error code 400.
func NewBadRequest(err error) *HTTPError {
	return &HTTPError{http.StatusBadRequest, err}
}

// NewBadRequestString returns a HttpError with the supplied message
// and error code 400.
func NewBadRequestString(s string) *HTTPError {
	return NewBadRequest(errors.New(s))
}

// NewBadRequestMissingParameter returns a 400 HttpError as a required
// parameter is missing in the HTTP request.
func NewBadRequestMissingParameter(s string) *HTTPError {
	return NewBadRequestString(`Missing parameter "` + s + `"`)
}

// NewBadRequestUnwantedParameter returns a 400 HttpError as a unnecessary
// parameter is present in the HTTP request.
func NewBadRequestUnwantedParameter(s string) *HTTPError {
	return NewBadRequestString(`Unwanted parameter "` + s + `"`)
}

D vendor/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers.go => vendor/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers.go +0 -48
@@ 1,48 0,0 @@
// Package derhelpers implements common functionality
// on DER encoded data
package derhelpers

import (
	"crypto"
	"crypto/ecdsa"
	"crypto/rsa"
	"crypto/x509"

	cferr "github.com/cloudflare/cfssl/errors"
	"golang.org/x/crypto/ed25519"
)

// ParsePrivateKeyDER parses a PKCS #1, PKCS #8, ECDSA, or Ed25519 DER-encoded
// private key. The key must not be in PEM format.
func ParsePrivateKeyDER(keyDER []byte) (key crypto.Signer, err error) {
	generalKey, err := x509.ParsePKCS8PrivateKey(keyDER)
	if err != nil {
		generalKey, err = x509.ParsePKCS1PrivateKey(keyDER)
		if err != nil {
			generalKey, err = x509.ParseECPrivateKey(keyDER)
			if err != nil {
				generalKey, err = ParseEd25519PrivateKey(keyDER)
				if err != nil {
					// We don't include the actual error into
					// the final error. The reason might be
					// we don't want to leak any info about
					// the private key.
					return nil, cferr.New(cferr.PrivateKeyError,
						cferr.ParseFailed)
				}
			}
		}
	}

	switch generalKey.(type) {
	case *rsa.PrivateKey:
		return generalKey.(*rsa.PrivateKey), nil
	case *ecdsa.PrivateKey:
		return generalKey.(*ecdsa.PrivateKey), nil
	case ed25519.PrivateKey:
		return generalKey.(ed25519.PrivateKey), nil
	}

	// should never reach here
	return nil, cferr.New(cferr.PrivateKeyError, cferr.ParseFailed)
}

D vendor/github.com/cloudflare/cfssl/helpers/derhelpers/ed25519.go => vendor/github.com/cloudflare/cfssl/helpers/derhelpers/ed25519.go +0 -133
@@ 1,133 0,0 @@
package derhelpers

import (
	"crypto"
	"crypto/x509/pkix"
	"encoding/asn1"
	"errors"

	"golang.org/x/crypto/ed25519"
)

var errEd25519WrongID = errors.New("incorrect object identifier")
var errEd25519WrongKeyType = errors.New("incorrect key type")

// ed25519OID is the OID for the Ed25519 signature scheme: see
// https://datatracker.ietf.org/doc/draft-ietf-curdle-pkix-04.
var ed25519OID = asn1.ObjectIdentifier{1, 3, 101, 112}

// subjectPublicKeyInfo reflects the ASN.1 object defined in the X.509 standard.
//
// This is defined in crypto/x509 as "publicKeyInfo".
type subjectPublicKeyInfo struct {
	Algorithm pkix.AlgorithmIdentifier
	PublicKey asn1.BitString
}

// MarshalEd25519PublicKey creates a DER-encoded SubjectPublicKeyInfo for an
// ed25519 public key, as defined in
// https://tools.ietf.org/html/draft-ietf-curdle-pkix-04. This is analagous to
// MarshalPKIXPublicKey in crypto/x509, which doesn't currently support Ed25519.
func MarshalEd25519PublicKey(pk crypto.PublicKey) ([]byte, error) {
	pub, ok := pk.(ed25519.PublicKey)
	if !ok {
		return nil, errEd25519WrongKeyType
	}

	spki := subjectPublicKeyInfo{
		Algorithm: pkix.AlgorithmIdentifier{
			Algorithm: ed25519OID,
		},
		PublicKey: asn1.BitString{
			BitLength: len(pub) * 8,
			Bytes:     pub,
		},
	}

	return asn1.Marshal(spki)
}

// ParseEd25519PublicKey returns the Ed25519 public key encoded by the input.
func ParseEd25519PublicKey(der []byte) (crypto.PublicKey, error) {
	var spki subjectPublicKeyInfo
	if rest, err := asn1.Unmarshal(der, &spki); err != nil {
		return nil, err
	} else if len(rest) > 0 {
		return nil, errors.New("SubjectPublicKeyInfo too long")
	}

	if !spki.Algorithm.Algorithm.Equal(ed25519OID) {
		return nil, errEd25519WrongID
	}

	if spki.PublicKey.BitLength != ed25519.PublicKeySize*8 {
		return nil, errors.New("SubjectPublicKeyInfo PublicKey length mismatch")
	}

	return ed25519.PublicKey(spki.PublicKey.Bytes), nil
}

// oneAsymmetricKey reflects the ASN.1 structure for storing private keys in
// https://tools.ietf.org/html/draft-ietf-curdle-pkix-04, excluding the optional
// fields, which we don't use here.
//
// This is identical to pkcs8 in crypto/x509.
type oneAsymmetricKey struct {
	Version    int
	Algorithm  pkix.AlgorithmIdentifier
	PrivateKey []byte
}

// curvePrivateKey is the innter type of the PrivateKey field of
// oneAsymmetricKey.
type curvePrivateKey []byte

// MarshalEd25519PrivateKey returns a DER encdoing of the input private key as
// specified in https://tools.ietf.org/html/draft-ietf-curdle-pkix-04.
func MarshalEd25519PrivateKey(sk crypto.PrivateKey) ([]byte, error) {
	priv, ok := sk.(ed25519.PrivateKey)
	if !ok {
		return nil, errEd25519WrongKeyType
	}

	// Marshal the innter CurvePrivateKey.
	curvePrivateKey, err := asn1.Marshal(priv.Seed())
	if err != nil {
		return nil, err
	}

	// Marshal the OneAsymmetricKey.
	asym := oneAsymmetricKey{
		Version: 0,
		Algorithm: pkix.AlgorithmIdentifier{
			Algorithm: ed25519OID,
		},
		PrivateKey: curvePrivateKey,
	}
	return asn1.Marshal(asym)
}

// ParseEd25519PrivateKey returns the Ed25519 private key encoded by the input.
func ParseEd25519PrivateKey(der []byte) (crypto.PrivateKey, error) {
	asym := new(oneAsymmetricKey)
	if rest, err := asn1.Unmarshal(der, asym); err != nil {
		return nil, err
	} else if len(rest) > 0 {
		return nil, errors.New("OneAsymmetricKey too long")
	}

	// Check that the key type is correct.
	if !asym.Algorithm.Algorithm.Equal(ed25519OID) {
		return nil, errEd25519WrongID
	}

	// Unmarshal the inner CurvePrivateKey.
	seed := new(curvePrivateKey)
	if rest, err := asn1.Unmarshal(asym.PrivateKey, seed); err != nil {
		return nil, err
	} else if len(rest) > 0 {
		return nil, errors.New("CurvePrivateKey too long")
	}

	return ed25519.NewKeyFromSeed(*seed), nil
}

D vendor/github.com/cloudflare/cfssl/helpers/helpers.go => vendor/github.com/cloudflare/cfssl/helpers/helpers.go +0 -590
@@ 1,590 0,0 @@
// Package helpers implements utility functionality common to many
// CFSSL packages.
package helpers

import (
	"bytes"
	"crypto"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"encoding/pem"
	"errors"
	"fmt"
	"io/ioutil"
	"os"

	"github.com/google/certificate-transparency-go"
	cttls "github.com/google/certificate-transparency-go/tls"
	ctx509 "github.com/google/certificate-transparency-go/x509"
	"golang.org/x/crypto/ocsp"

	"strings"
	"time"

	"github.com/cloudflare/cfssl/crypto/pkcs7"
	cferr "github.com/cloudflare/cfssl/errors"
	"github.com/cloudflare/cfssl/helpers/derhelpers"
	"github.com/cloudflare/cfssl/log"
	"golang.org/x/crypto/pkcs12"
)

// OneYear is a time.Duration representing a year's worth of seconds.
const OneYear = 8760 * time.Hour

// OneDay is a time.Duration representing a day's worth of seconds.
const OneDay = 24 * time.Hour

// InclusiveDate returns the time.Time representation of a date - 1
// nanosecond. This allows time.After to be used inclusively.
func InclusiveDate(year int, month time.Month, day int) time.Time {
	return time.Date(year, month, day, 0, 0, 0, 0, time.UTC).Add(-1 * time.Nanosecond)
}

// Jul2012 is the July 2012 CAB Forum deadline for when CAs must stop
// issuing certificates valid for more than 5 years.
var Jul2012 = InclusiveDate(2012, time.July, 01)

// Apr2015 is the April 2015 CAB Forum deadline for when CAs must stop
// issuing certificates valid for more than 39 months.
var Apr2015 = InclusiveDate(2015, time.April, 01)

// KeyLength returns the bit size of ECDSA or RSA PublicKey
func KeyLength(key interface{}) int {
	if key == nil {
		return 0
	}
	if ecdsaKey, ok := key.(*ecdsa.PublicKey); ok {
		return ecdsaKey.Curve.Params().BitSize
	} else if rsaKey, ok := key.(*rsa.PublicKey); ok {
		return rsaKey.N.BitLen()
	}

	return 0
}

// ExpiryTime returns the time when the certificate chain is expired.
func ExpiryTime(chain []*x509.Certificate) (notAfter time.Time) {
	if len(chain) == 0 {
		return
	}

	notAfter = chain[0].NotAfter
	for _, cert := range chain {
		if notAfter.After(cert.NotAfter) {
			notAfter = cert.NotAfter
		}
	}
	return
}

// MonthsValid returns the number of months for which a certificate is valid.
func MonthsValid(c *x509.Certificate) int {
	issued := c.NotBefore
	expiry := c.NotAfter
	years := (expiry.Year() - issued.Year())
	months := years*12 + int(expiry.Month()) - int(issued.Month())

	// Round up if valid for less than a full month
	if expiry.Day() > issued.Day() {
		months++
	}
	return months
}

// ValidExpiry determines if a certificate is valid for an acceptable
// length of time per the CA/Browser Forum baseline requirements.
// See https://cabforum.org/wp-content/uploads/CAB-Forum-BR-1.3.0.pdf
func ValidExpiry(c *x509.Certificate) bool {
	issued := c.NotBefore

	var maxMonths int
	switch {
	case issued.After(Apr2015):
		maxMonths = 39
	case issued.After(Jul2012):
		maxMonths = 60
	case issued.Before(Jul2012):
		maxMonths = 120
	}

	if MonthsValid(c) > maxMonths {
		return false
	}
	return true
}

// SignatureString returns the TLS signature string corresponding to
// an X509 signature algorithm.
func SignatureString(alg x509.SignatureAlgorithm) string {
	switch alg {
	case x509.MD2WithRSA:
		return "MD2WithRSA"
	case x509.MD5WithRSA:
		return "MD5WithRSA"
	case x509.SHA1WithRSA:
		return "SHA1WithRSA"
	case x509.SHA256WithRSA:
		return "SHA256WithRSA"
	case x509.SHA384WithRSA:
		return "SHA384WithRSA"
	case x509.SHA512WithRSA:
		return "SHA512WithRSA"
	case x509.DSAWithSHA1:
		return "DSAWithSHA1"
	case x509.DSAWithSHA256:
		return "DSAWithSHA256"
	case x509.ECDSAWithSHA1:
		return "ECDSAWithSHA1"
	case x509.ECDSAWithSHA256:
		return "ECDSAWithSHA256"
	case x509.ECDSAWithSHA384:
		return "ECDSAWithSHA384"
	case x509.ECDSAWithSHA512:
		return "ECDSAWithSHA512"
	default:
		return "Unknown Signature"
	}
}

// HashAlgoString returns the hash algorithm name contains in the signature
// method.
func HashAlgoString(alg x509.SignatureAlgorithm) string {
	switch alg {
	case x509.MD2WithRSA:
		return "MD2"
	case x509.MD5WithRSA:
		return "MD5"
	case x509.SHA1WithRSA:
		return "SHA1"
	case x509.SHA256WithRSA:
		return "SHA256"
	case x509.SHA384WithRSA:
		return "SHA384"
	case x509.SHA512WithRSA:
		return "SHA512"
	case x509.DSAWithSHA1:
		return "SHA1"
	case x509.DSAWithSHA256:
		return "SHA256"
	case x509.ECDSAWithSHA1:
		return "SHA1"
	case x509.ECDSAWithSHA256:
		return "SHA256"
	case x509.ECDSAWithSHA384:
		return "SHA384"
	case x509.ECDSAWithSHA512:
		return "SHA512"
	default:
		return "Unknown Hash Algorithm"
	}
}

// StringTLSVersion returns underlying enum values from human names for TLS
// versions, defaults to current golang default of TLS 1.0
func StringTLSVersion(version string) uint16 {
	switch version {
	case "1.2":
		return tls.VersionTLS12
	case "1.1":
		return tls.VersionTLS11
	default:
		return tls.VersionTLS10
	}
}

// EncodeCertificatesPEM encodes a number of x509 certificates to PEM
func EncodeCertificatesPEM(certs []*x509.Certificate) []byte {
	var buffer bytes.Buffer
	for _, cert := range certs {
		pem.Encode(&buffer, &pem.Block{
			Type:  "CERTIFICATE",
			Bytes: cert.Raw,
		})
	}

	return buffer.Bytes()
}

// EncodeCertificatePEM encodes a single x509 certificates to PEM
func EncodeCertificatePEM(cert *x509.Certificate) []byte {
	return EncodeCertificatesPEM([]*x509.Certificate{cert})
}

// ParseCertificatesPEM parses a sequence of PEM-encoded certificate and returns them,
// can handle PEM encoded PKCS #7 structures.
func ParseCertificatesPEM(certsPEM []byte) ([]*x509.Certificate, error) {
	var certs []*x509.Certificate
	var err error
	certsPEM = bytes.TrimSpace(certsPEM)
	for len(certsPEM) > 0 {
		var cert []*x509.Certificate
		cert, certsPEM, err = ParseOneCertificateFromPEM(certsPEM)
		if err != nil {

			return nil, cferr.New(cferr.CertificateError, cferr.ParseFailed)
		} else if cert == nil {
			break
		}

		certs = append(certs, cert...)
	}
	if len(certsPEM) > 0 {
		return nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed)
	}
	return certs, nil
}

// ParseCertificatesDER parses a DER encoding of a certificate object and possibly private key,
// either PKCS #7, PKCS #12, or raw x509.
func ParseCertificatesDER(certsDER []byte, password string) (certs []*x509.Certificate, key crypto.Signer, err error) {
	certsDER = bytes.TrimSpace(certsDER)
	pkcs7data, err := pkcs7.ParsePKCS7(certsDER)
	if err != nil {
		var pkcs12data interface{}
		certs = make([]*x509.Certificate, 1)
		pkcs12data, certs[0], err = pkcs12.Decode(certsDER, password)
		if err != nil {
			certs, err = x509.ParseCertificates(certsDER)
			if err != nil {
				return nil, nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed)
			}
		} else {
			key = pkcs12data.(crypto.Signer)
		}
	} else {
		if pkcs7data.ContentInfo != "SignedData" {
			return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.DecodeFailed, errors.New("can only extract certificates from signed data content info"))
		}
		certs = pkcs7data.Content.SignedData.Certificates
	}
	if certs == nil {
		return nil, key, cferr.New(cferr.CertificateError, cferr.DecodeFailed)
	}
	return certs, key, nil
}

// ParseSelfSignedCertificatePEM parses a PEM-encoded certificate and check if it is self-signed.
func ParseSelfSignedCertificatePEM(certPEM []byte) (*x509.Certificate, error) {
	cert, err := ParseCertificatePEM(certPEM)
	if err != nil {
		return nil, err
	}

	if err := cert.CheckSignature(cert.SignatureAlgorithm, cert.RawTBSCertificate, cert.Signature); err != nil {
		return nil, cferr.Wrap(cferr.CertificateError, cferr.VerifyFailed, err)
	}
	return cert, nil
}

// ParseCertificatePEM parses and returns a PEM-encoded certificate,
// can handle PEM encoded PKCS #7 structures.
func ParseCertificatePEM(certPEM []byte) (*x509.Certificate, error) {
	certPEM = bytes.TrimSpace(certPEM)
	cert, rest, err := ParseOneCertificateFromPEM(certPEM)
	if err != nil {
		// Log the actual parsing error but throw a default parse error message.
		log.Debugf("Certificate parsing error: %v", err)
		return nil, cferr.New(cferr.CertificateError, cferr.ParseFailed)
	} else if cert == nil {
		return nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed)
	} else if len(rest) > 0 {
		return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("the PEM file should contain only one object"))
	} else if len(cert) > 1 {
		return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("the PKCS7 object in the PEM file should contain only one certificate"))
	}
	return cert[0], nil
}

// ParseOneCertificateFromPEM attempts to parse one PEM encoded certificate object,
// either a raw x509 certificate or a PKCS #7 structure possibly containing
// multiple certificates, from the top of certsPEM, which itself may
// contain multiple PEM encoded certificate objects.
func ParseOneCertificateFromPEM(certsPEM []byte) ([]*x509.Certificate, []byte, error) {

	block, rest := pem.Decode(certsPEM)
	if block == nil {
		return nil, rest, nil
	}

	cert, err := x509.ParseCertificate(block.Bytes)
	if err != nil {
		pkcs7data, err := pkcs7.ParsePKCS7(block.Bytes)
		if err != nil {
			return nil, rest, err
		}
		if pkcs7data.ContentInfo != "SignedData" {
			return nil, rest, errors.New("only PKCS #7 Signed Data Content Info supported for certificate parsing")
		}
		certs := pkcs7data.Content.SignedData.Certificates
		if certs == nil {
			return nil, rest, errors.New("PKCS #7 structure contains no certificates")
		}
		return certs, rest, nil
	}
	var certs = []*x509.Certificate{cert}
	return certs, rest, nil
}

// LoadPEMCertPool loads a pool of PEM certificates from file.
func LoadPEMCertPool(certsFile string) (*x509.CertPool, error) {
	if certsFile == "" {
		return nil, nil
	}
	pemCerts, err := ioutil.ReadFile(certsFile)
	if err != nil {
		return nil, err
	}

	return PEMToCertPool(pemCerts)
}

// PEMToCertPool concerts PEM certificates to a CertPool.
func PEMToCertPool(pemCerts []byte) (*x509.CertPool, error) {
	if len(pemCerts) == 0 {
		return nil, nil
	}

	certPool := x509.NewCertPool()
	if !certPool.AppendCertsFromPEM(pemCerts) {
		return nil, errors.New("failed to load cert pool")
	}

	return certPool, nil
}

// ParsePrivateKeyPEM parses and returns a PEM-encoded private
// key. The private key may be either an unencrypted PKCS#8, PKCS#1,
// or elliptic private key.
func ParsePrivateKeyPEM(keyPEM []byte) (key crypto.Signer, err error) {
	return ParsePrivateKeyPEMWithPassword(keyPEM, nil)
}

// ParsePrivateKeyPEMWithPassword parses and returns a PEM-encoded private
// key. The private key may be a potentially encrypted PKCS#8, PKCS#1,
// or elliptic private key.
func ParsePrivateKeyPEMWithPassword(keyPEM []byte, password []byte) (key crypto.Signer, err error) {
	keyDER, err := GetKeyDERFromPEM(keyPEM, password)
	if err != nil {
		return nil, err
	}

	return derhelpers.ParsePrivateKeyDER(keyDER)
}

// GetKeyDERFromPEM parses a PEM-encoded private key and returns DER-format key bytes.
func GetKeyDERFromPEM(in []byte, password []byte) ([]byte, error) {
	keyDER, _ := pem.Decode(in)
	if keyDER != nil {
		if procType, ok := keyDER.Headers["Proc-Type"]; ok {
			if strings.Contains(procType, "ENCRYPTED") {
				if password != nil {
					return x509.DecryptPEMBlock(keyDER, password)
				}
				return nil, cferr.New(cferr.PrivateKeyError, cferr.Encrypted)
			}
		}
		return keyDER.Bytes, nil
	}

	return nil, cferr.New(cferr.PrivateKeyError, cferr.DecodeFailed)
}

// ParseCSR parses a PEM- or DER-encoded PKCS #10 certificate signing request.
func ParseCSR(in []byte) (csr *x509.CertificateRequest, rest []byte, err error) {
	in = bytes.TrimSpace(in)
	p, rest := pem.Decode(in)
	if p != nil {
		if p.Type != "NEW CERTIFICATE REQUEST" && p.Type != "CERTIFICATE REQUEST" {
			return nil, rest, cferr.New(cferr.CSRError, cferr.BadRequest)
		}

		csr, err = x509.ParseCertificateRequest(p.Bytes)
	} else {
		csr, err = x509.ParseCertificateRequest(in)
	}

	if err != nil {
		return nil, rest, err
	}

	err = csr.CheckSignature()
	if err != nil {
		return nil, rest, err
	}

	return csr, rest, nil
}

// ParseCSRPEM parses a PEM-encoded certificate signing request.
// It does not check the signature. This is useful for dumping data from a CSR
// locally.
func ParseCSRPEM(csrPEM []byte) (*x509.CertificateRequest, error) {
	block, _ := pem.Decode([]byte(csrPEM))
	if block == nil {
		return nil, cferr.New(cferr.CSRError, cferr.DecodeFailed)
	}
	csrObject, err := x509.ParseCertificateRequest(block.Bytes)

	if err != nil {
		return nil, err
	}

	return csrObject, nil
}

// SignerAlgo returns an X.509 signature algorithm from a crypto.Signer.
func SignerAlgo(priv crypto.Signer) x509.SignatureAlgorithm {
	switch pub := priv.Public().(type) {
	case *rsa.PublicKey:
		bitLength := pub.N.BitLen()
		switch {
		case bitLength >= 4096:
			return x509.SHA512WithRSA
		case bitLength >= 3072:
			return x509.SHA384WithRSA
		case bitLength >= 2048:
			return x509.SHA256WithRSA
		default:
			return x509.SHA1WithRSA
		}
	case *ecdsa.PublicKey:
		switch pub.Curve {
		case elliptic.P521():
			return x509.ECDSAWithSHA512
		case elliptic.P384():
			return x509.ECDSAWithSHA384
		case elliptic.P256():
			return x509.ECDSAWithSHA256
		default:
			return x509.ECDSAWithSHA1
		}
	default:
		return x509.UnknownSignatureAlgorithm
	}
}

// LoadClientCertificate load key/certificate from pem files
func LoadClientCertificate(certFile string, keyFile string) (*tls.Certificate, error) {
	if certFile != "" && keyFile != "" {
		cert, err := tls.LoadX509KeyPair(certFile, keyFile)
		if err != nil {
			log.Criticalf("Unable to read client certificate from file: %s or key from file: %s", certFile, keyFile)
			return nil, err
		}
		log.Debug("Client certificate loaded ")
		return &cert, nil
	}
	return nil, nil
}

// CreateTLSConfig creates a tls.Config object from certs and roots
func CreateTLSConfig(remoteCAs *x509.CertPool, cert *tls.Certificate) *tls.Config {
	var certs []tls.Certificate
	if cert != nil {
		certs = []tls.Certificate{*cert}
	}
	return &tls.Config{
		Certificates: certs,
		RootCAs:      remoteCAs,
	}
}

// SerializeSCTList serializes a list of SCTs.
func SerializeSCTList(sctList []ct.SignedCertificateTimestamp) ([]byte, error) {
	list := ctx509.SignedCertificateTimestampList{}
	for _, sct := range sctList {
		sctBytes, err := cttls.Marshal(sct)
		if err != nil {
			return nil, err
		}
		list.SCTList = append(list.SCTList, ctx509.SerializedSCT{Val: sctBytes})
	}
	return cttls.Marshal(list)
}

// DeserializeSCTList deserializes a list of SCTs.
func DeserializeSCTList(serializedSCTList []byte) ([]ct.SignedCertificateTimestamp, error) {
	var sctList ctx509.SignedCertificateTimestampList
	rest, err := cttls.Unmarshal(serializedSCTList, &sctList)
	if err != nil {
		return nil, err
	}
	if len(rest) != 0 {
		return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, errors.New("serialized SCT list contained trailing garbage"))
	}
	list := make([]ct.SignedCertificateTimestamp, len(sctList.SCTList))
	for i, serializedSCT := range sctList.SCTList {
		var sct ct.SignedCertificateTimestamp
		rest, err := cttls.Unmarshal(serializedSCT.Val, &sct)
		if err != nil {
			return nil, err
		}
		if len(rest) != 0 {
			return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, errors.New("serialized SCT contained trailing garbage"))
		}
		list[i] = sct
	}
	return list, nil
}

// SCTListFromOCSPResponse extracts the SCTList from an ocsp.Response,
// returning an empty list if the SCT extension was not found or could not be
// unmarshalled.
func SCTListFromOCSPResponse(response *ocsp.Response) ([]ct.SignedCertificateTimestamp, error) {
	// This loop finds the SCTListExtension in the OCSP response.
	var SCTListExtension, ext pkix.Extension
	for _, ext = range response.Extensions {
		// sctExtOid is the ObjectIdentifier of a Signed Certificate Timestamp.
		sctExtOid := asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 5}
		if ext.Id.Equal(sctExtOid) {
			SCTListExtension = ext
			break
		}
	}

	// This code block extracts the sctList from the SCT extension.
	var sctList []ct.SignedCertificateTimestamp
	var err error
	if numBytes := len(SCTListExtension.Value); numBytes != 0 {
		var serializedSCTList []byte
		rest := make([]byte, numBytes)
		copy(rest, SCTListExtension.Value)
		for len(rest) != 0 {
			rest, err = asn1.Unmarshal(rest, &serializedSCTList)
			if err != nil {
				return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, err)
			}
		}
		sctList, err = DeserializeSCTList(serializedSCTList)
	}
	return sctList, err
}

// ReadBytes reads a []byte either from a file or an environment variable.
// If valFile has a prefix of 'env:', the []byte is read from the environment
// using the subsequent name. If the prefix is 'file:' the []byte is read from
// the subsequent file. If no prefix is provided, valFile is assumed to be a
// file path.
func ReadBytes(valFile string) ([]byte, error) {
	switch splitVal := strings.SplitN(valFile, ":", 2); len(splitVal) {
	case 1:
		return ioutil.ReadFile(valFile)
	case 2:
		switch splitVal[0] {
		case "env":
			return []byte(os.Getenv(splitVal[1])), nil
		case "file":
			return ioutil.ReadFile(splitVal[1])
		default:
			return nil, fmt.Errorf("unknown prefix: %s", splitVal[0])
		}
	default:
		return nil, fmt.Errorf("multiple prefixes: %s",
			strings.Join(splitVal[:len(splitVal)-1], ", "))
	}
}

D vendor/github.com/cloudflare/cfssl/log/log.go => vendor/github.com/cloudflare/cfssl/log/log.go +0 -162
@@ 1,162 0,0 @@
// Package log implements a wrapper around the Go standard library's
// logging package. Clients should set the current log level; only
// messages below that level will actually be logged. For example, if
// Level is set to LevelWarning, only log messages at the Warning,
// Error, and Critical levels will be logged.
package log

import (
	"fmt"
	"log"
	"os"
)

// The following constants represent logging levels in increasing levels of seriousness.
const (
	// LevelDebug is the log level for Debug statements.
	LevelDebug = iota
	// LevelInfo is the log level for Info statements.
	LevelInfo
	// LevelWarning is the log level for Warning statements.
	LevelWarning
	// LevelError is the log level for Error statements.
	LevelError
	// LevelCritical is the log level for Critical statements.
	LevelCritical
	// LevelFatal is the log level for Fatal statements.
	LevelFatal
)

var levelPrefix = [...]string{
	LevelDebug:    "DEBUG",
	LevelInfo:     "INFO",
	LevelWarning:  "WARNING",
	LevelError:    "ERROR",
	LevelCritical: "CRITICAL",
	LevelFatal:    "FATAL",
}

// Level stores the current logging level.
var Level = LevelInfo

// SyslogWriter specifies the necessary methods for an alternate output
// destination passed in via SetLogger.
//
// SyslogWriter is satisfied by *syslog.Writer.
type SyslogWriter interface {
	Debug(string)
	Info(string)
	Warning(string)
	Err(string)
	Crit(string)
	Emerg(string)
}

// syslogWriter stores the SetLogger() parameter.
var syslogWriter SyslogWriter

// SetLogger sets the output used for output by this package.
// A *syslog.Writer is a good choice for the logger parameter.
// Call with a nil parameter to revert to default behavior.
func SetLogger(logger SyslogWriter) {
	syslogWriter = logger
}

func print(l int, msg string) {
	if l >= Level {
		if syslogWriter != nil {
			switch l {
			case LevelDebug:
				syslogWriter.Debug(msg)
			case LevelInfo:
				syslogWriter.Info(msg)
			case LevelWarning:
				syslogWriter.Warning(msg)
			case LevelError:
				syslogWriter.Err(msg)
			case LevelCritical:
				syslogWriter.Crit(msg)
			case LevelFatal:
				syslogWriter.Emerg(msg)
			}
		} else {
			log.Printf("[%s] %s", levelPrefix[l], msg)
		}
	}
}

func outputf(l int, format string, v []interface{}) {
	print(l, fmt.Sprintf(format, v...))
}

func output(l int, v []interface{}) {
	print(l, fmt.Sprint(v...))
}

// Fatalf logs a formatted message at the "fatal" level and then exits. The
// arguments are handled in the same manner as fmt.Printf.
func Fatalf(format string, v ...interface{}) {
	outputf(LevelFatal, format, v)
	os.Exit(1)
}

// Fatal logs its arguments at the "fatal" level and then exits.
func Fatal(v ...interface{}) {
	output(LevelFatal, v)
	os.Exit(1)
}

// Criticalf logs a formatted message at the "critical" level. The
// arguments are handled in the same manner as fmt.Printf.
func Criticalf(format string, v ...interface{}) {
	outputf(LevelCritical, format, v)
}

// Critical logs its arguments at the "critical" level.
func Critical(v ...interface{}) {
	output(LevelCritical, v)
}

// Errorf logs a formatted message at the "error" level. The arguments
// are handled in the same manner as fmt.Printf.
func Errorf(format string, v ...interface{}) {
	outputf(LevelError, format, v)
}

// Error logs its arguments at the "error" level.
func Error(v ...interface{}) {
	output(LevelError, v)
}

// Warningf logs a formatted message at the "warning" level. The
// arguments are handled in the same manner as fmt.Printf.
func Warningf(format string, v ...interface{}) {
	outputf(LevelWarning, format, v)
}

// Warning logs its arguments at the "warning" level.
func Warning(v ...interface{}) {
	output(LevelWarning, v)
}

// Infof logs a formatted message at the "info" level. The arguments
// are handled in the same manner as fmt.Printf.
func Infof(format string, v ...interface{}) {
	outputf(LevelInfo, format, v)
}

// Info logs its arguments at the "info" level.
func Info(v ...interface{}) {
	output(LevelInfo, v)
}

// Debugf logs a formatted message at the "debug" level. The arguments
// are handled in the same manner as fmt.Printf.
func Debugf(format string, v ...interface{}) {
	outputf(LevelDebug, format, v)
}

// Debug logs its arguments at the "debug" level.
func Debug(v ...interface{}) {
	output(LevelDebug, v)
}

D vendor/github.com/cloudflare/cfssl/revoke/revoke.go => vendor/github.com/cloudflare/cfssl/revoke/revoke.go +0 -336
@@ 1,336 0,0 @@
// Package revoke provides functionality for checking the validity of
// a cert. Specifically, the temporal validity of the certificate is
// checked first, then any CRL and OCSP url in the cert is checked.
package revoke

import (
	"bytes"
	"crypto"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/base64"
	"encoding/pem"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	neturl "net/url"
	"sync"
	"time"

	"golang.org/x/crypto/ocsp"

	"github.com/cloudflare/cfssl/helpers"
	"github.com/cloudflare/cfssl/log"
)

// HardFail determines whether the failure to check the revocation
// status of a certificate (i.e. due to network failure) causes
// verification to fail (a hard failure).
var HardFail = false

// CRLSet associates a PKIX certificate list with the URL the CRL is
// fetched from.
var CRLSet = map[string]*pkix.CertificateList{}
var crlLock = new(sync.Mutex)

// We can't handle LDAP certificates, so this checks to see if the
// URL string points to an LDAP resource so that we can ignore it.
func ldapURL(url string) bool {
	u, err := neturl.Parse(url)
	if err != nil {
		log.Warningf("error parsing url %s: %v", url, err)
		return false
	}
	if u.Scheme == "ldap" {
		return true
	}
	return false
}

// revCheck should check the certificate for any revocations. It
// returns a pair of booleans: the first indicates whether the certificate
// is revoked, the second indicates whether the revocations were
// successfully checked.. This leads to the following combinations:
//
//  false, false: an error was encountered while checking revocations.
//
//  false, true:  the certificate was checked successfully and
//                  it is not revoked.
//
//  true, true:   the certificate was checked successfully and
//                  it is revoked.
//
//  true, false:  failure to check revocation status causes
//                  verification to fail
func revCheck(cert *x509.Certificate) (revoked, ok bool, err error) {
	for _, url := range cert.CRLDistributionPoints {
		if ldapURL(url) {
			log.Infof("skipping LDAP CRL: %s", url)
			continue
		}

		if revoked, ok, err := certIsRevokedCRL(cert, url); !ok {
			log.Warning("error checking revocation via CRL")
			if HardFail {
				return true, false, err
			}
			return false, false, err
		} else if revoked {
			log.Info("certificate is revoked via CRL")
			return true, true, err
		}
	}

	if revoked, ok, err := certIsRevokedOCSP(cert, HardFail); !ok {
		log.Warning("error checking revocation via OCSP")
		if HardFail {
			return true, false, err
		}
		return false, false, err
	} else if revoked {
		log.Info("certificate is revoked via OCSP")
		return true, true, err
	}

	return false, true, nil
}

// fetchCRL fetches and parses a CRL.
func fetchCRL(url string) (*pkix.CertificateList, error) {
	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	} else if resp.StatusCode >= 300 {
		return nil, errors.New("failed to retrieve CRL")
	}

	body, err := crlRead(resp.Body)
	if err != nil {
		return nil, err
	}
	resp.Body.Close()

	return x509.ParseCRL(body)
}

func getIssuer(cert *x509.Certificate) *x509.Certificate {
	var issuer *x509.Certificate
	var err error
	for _, issuingCert := range cert.IssuingCertificateURL {
		issuer, err = fetchRemote(issuingCert)
		if err != nil {
			continue
		}
		break
	}

	return issuer

}

// check a cert against a specific CRL. Returns the same bool pair
// as revCheck, plus an error if one occurred.
func certIsRevokedCRL(cert *x509.Certificate, url string) (revoked, ok bool, err error) {
	crl, ok := CRLSet[url]
	if ok && crl == nil {
		ok = false
		crlLock.Lock()
		delete(CRLSet, url)
		crlLock.Unlock()
	}

	var shouldFetchCRL = true
	if ok {
		if !crl.HasExpired(time.Now()) {
			shouldFetchCRL = false
		}
	}

	issuer := getIssuer(cert)

	if shouldFetchCRL {
		var err error
		crl, err = fetchCRL(url)
		if err != nil {
			log.Warningf("failed to fetch CRL: %v", err)
			return false, false, err
		}

		// check CRL signature
		if issuer != nil {
			err = issuer.CheckCRLSignature(crl)
			if err != nil {
				log.Warningf("failed to verify CRL: %v", err)
				return false, false, err
			}
		}

		crlLock.Lock()
		CRLSet[url] = crl
		crlLock.Unlock()
	}

	for _, revoked := range crl.TBSCertList.RevokedCertificates {
		if cert.SerialNumber.Cmp(revoked.SerialNumber) == 0 {
			log.Info("Serial number match: intermediate is revoked.")
			return true, true, err
		}
	}

	return false, true, err
}

// VerifyCertificate ensures that the certificate passed in hasn't
// expired and checks the CRL for the server.
func VerifyCertificate(cert *x509.Certificate) (revoked, ok bool) {
	revoked, ok, _ = VerifyCertificateError(cert)
	return revoked, ok
}

// VerifyCertificateError ensures that the certificate passed in hasn't
// expired and checks the CRL for the server.
func VerifyCertificateError(cert *x509.Certificate) (revoked, ok bool, err error) {
	if !time.Now().Before(cert.NotAfter) {
		msg := fmt.Sprintf("Certificate expired %s\n", cert.NotAfter)
		log.Info(msg)
		return true, true, fmt.Errorf(msg)
	} else if !time.Now().After(cert.NotBefore) {
		msg := fmt.Sprintf("Certificate isn't valid until %s\n", cert.NotBefore)
		log.Info(msg)
		return true, true, fmt.Errorf(msg)
	}
	return revCheck(cert)
}

func fetchRemote(url string) (*x509.Certificate, error) {
	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	}

	in, err := remoteRead(resp.Body)
	if err != nil {
		return nil, err
	}
	resp.Body.Close()

	p, _ := pem.Decode(in)
	if p != nil {
		return helpers.ParseCertificatePEM(in)
	}

	return x509.ParseCertificate(in)
}

var ocspOpts = ocsp.RequestOptions{
	Hash: crypto.SHA1,
}

func certIsRevokedOCSP(leaf *x509.Certificate, strict bool) (revoked, ok bool, e error) {
	var err error

	ocspURLs := leaf.OCSPServer
	if len(ocspURLs) == 0 {
		// OCSP not enabled for this certificate.
		return false, true, nil
	}

	issuer := getIssuer(leaf)

	if issuer == nil {
		return false, false, nil
	}

	ocspRequest, err := ocsp.CreateRequest(leaf, issuer, &ocspOpts)
	if err != nil {
		return revoked, ok, err
	}

	for _, server := range ocspURLs {
		resp, err := sendOCSPRequest(server, ocspRequest, leaf, issuer)
		if err != nil {
			if strict {
				return revoked, ok, err
			}
			continue
		}

		// There wasn't an error fetching the OCSP status.
		ok = true

		if resp.Status != ocsp.Good {
			// The certificate was revoked.
			revoked = true
		}

		return revoked, ok, err
	}
	return revoked, ok, err
}

// sendOCSPRequest attempts to request an OCSP response from the
// server. The error only indicates a failure to *fetch* the
// certificate, and *does not* mean the certificate is valid.
func sendOCSPRequest(server string, req []byte, leaf, issuer *x509.Certificate) (*ocsp.Response, error) {
	var resp *http.Response
	var err error
	if len(req) > 256 {
		buf := bytes.NewBuffer(req)
		resp, err = http.Post(server, "application/ocsp-request", buf)
	} else {
		reqURL := server + "/" + neturl.QueryEscape(base64.StdEncoding.EncodeToString(req))
		resp, err = http.Get(reqURL)
	}

	if err != nil {
		return nil, err
	}

	if resp.StatusCode != http.StatusOK {
		return nil, errors.New("failed to retrieve OSCP")
	}

	body, err := ocspRead(resp.Body)
	if err != nil {
		return nil, err
	}
	resp.Body.Close()

	switch {
	case bytes.Equal(body, ocsp.UnauthorizedErrorResponse):
		return nil, errors.New("OSCP unauthorized")
	case bytes.Equal(body, ocsp.MalformedRequestErrorResponse):
		return nil, errors.New("OSCP malformed")
	case bytes.Equal(body, ocsp.InternalErrorErrorResponse):
		return nil, errors.New("OSCP internal error")
	case bytes.Equal(body, ocsp.TryLaterErrorResponse):
		return nil, errors.New("OSCP try later")
	case bytes.Equal(body, ocsp.SigRequredErrorResponse):
		return nil, errors.New("OSCP signature required")
	}

	return ocsp.ParseResponseForCert(body, leaf, issuer)
}

var crlRead = ioutil.ReadAll

// SetCRLFetcher sets the function to use to read from the http response body
func SetCRLFetcher(fn func(io.Reader) ([]byte, error)) {
	crlRead = fn
}

var remoteRead = ioutil.ReadAll

// SetRemoteFetcher sets the function to use to read from the http response body
func SetRemoteFetcher(fn func(io.Reader) ([]byte, error)) {
	remoteRead = fn
}

var ocspRead = ioutil.ReadAll

// SetOCSPFetcher sets the function to use to read from the http response body
func SetOCSPFetcher(fn func(io.Reader) ([]byte, error)) {
	ocspRead = fn
}

D vendor/github.com/dgrijalva/jwt-go/.gitignore => vendor/github.com/dgrijalva/jwt-go/.gitignore +0 -4
@@ 1,4 0,0 @@
.DS_Store
bin



D vendor/github.com/dgrijalva/jwt-go/.travis.yml => vendor/github.com/dgrijalva/jwt-go/.travis.yml +0 -13
@@ 1,13 0,0 @@
language: go

script:
    - go vet ./...
    - go test -v ./...

go:
  - 1.3
  - 1.4
  - 1.5
  - 1.6
  - 1.7
  - tip

D vendor/github.com/dgrijalva/jwt-go/LICENSE => vendor/github.com/dgrijalva/jwt-go/LICENSE +0 -8
@@ 1,8 0,0 @@
Copyright (c) 2012 Dave Grijalva

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


D vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md => vendor/github.com/dgrijalva/jwt-go/MIGRATION_GUIDE.md +0 -97
@@ 1,97 0,0 @@
## Migration Guide from v2 -> v3

Version 3 adds several new, frequently requested features.  To do so, it introduces a few breaking changes.  We've worked to keep these as minimal as possible.  This guide explains the breaking changes and how you can quickly update your code.

### `Token.Claims` is now an interface type

The most requested feature from the 2.0 verison of this library was the ability to provide a custom type to the JSON parser for claims. This was implemented by introducing a new interface, `Claims`, to replace `map[string]interface{}`.  We also included two concrete implementations of `Claims`: `MapClaims` and `StandardClaims`.

`MapClaims` is an alias for `map[string]interface{}` with built in validation behavior.  It is the default claims type when using `Parse`.  The usage is unchanged except you must type cast the claims property.

The old example for parsing a token looked like this..

```go
	if token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil {
		fmt.Printf("Token for user %v expires %v", token.Claims["user"], token.Claims["exp"])
	}
```

is now directly mapped to...

```go
	if token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil {
		claims := token.Claims.(jwt.MapClaims)
		fmt.Printf("Token for user %v expires %v", claims["user"], claims["exp"])
	}
```

`StandardClaims` is designed to be embedded in your custom type.  You can supply a custom claims type with the new `ParseWithClaims` function.  Here's an example of using a custom claims type.

```go
	type MyCustomClaims struct {
		User string
		*StandardClaims
	}
	
	if token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, keyLookupFunc); err == nil {
		claims := token.Claims.(*MyCustomClaims)
		fmt.Printf("Token for user %v expires %v", claims.User, claims.StandardClaims.ExpiresAt)
	}
```

### `ParseFromRequest` has been moved

To keep this library focused on the tokens without becoming overburdened with complex request processing logic, `ParseFromRequest` and its new companion `ParseFromRequestWithClaims` have been moved to a subpackage, `request`.  The method signatues have also been augmented to receive a new argument: `Extractor`.

`Extractors` do the work of picking the token string out of a request.  The interface is simple and composable.

This simple parsing example:

```go
	if token, err := jwt.ParseFromRequest(tokenString, req, keyLookupFunc); err == nil {
		fmt.Printf("Token for user %v expires %v", token.Claims["user"], token.Claims["exp"])
	}
```

is directly mapped to:

```go
	if token, err := request.ParseFromRequest(req, request.OAuth2Extractor, keyLookupFunc); err == nil {
		claims := token.Claims.(jwt.MapClaims)
		fmt.Printf("Token for user %v expires %v", claims["user"], claims["exp"])
	}
```

There are several concrete `Extractor` types provided for your convenience:

* `HeaderExtractor` will search a list of headers until one contains content.
* `ArgumentExtractor` will search a list of keys in request query and form arguments until one contains content.
* `MultiExtractor` will try a list of `Extractors` in order until one returns content.
* `AuthorizationHeaderExtractor` will look in the `Authorization` header for a `Bearer` token.
* `OAuth2Extractor` searches the places an OAuth2 token would be specified (per the spec): `Authorization` header and `access_token` argument
* `PostExtractionFilter` wraps an `Extractor`, allowing you to process the content before it's parsed.  A simple example is stripping the `Bearer ` text from a header


### RSA signing methods no longer accept `[]byte` keys

Due to a [critical vulnerability](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/), we've decided the convenience of accepting `[]byte` instead of `rsa.PublicKey` or `rsa.PrivateKey` isn't worth the risk of misuse.

To replace this behavior, we've added two helper methods: `ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error)` and `ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error)`.  These are just simple helpers for unpacking PEM encoded PKCS1 and PKCS8 keys. If your keys are encoded any other way, all you need to do is convert them to the `crypto/rsa` package's types.

```go 
	func keyLookupFunc(*Token) (interface{}, error) {
		// Don't forget to validate the alg is what you expect:
		if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
		}
		
		// Look up key 
		key, err := lookupPublicKey(token.Header["kid"])
		if err != nil {
			return nil, err
		}
		
		// Unpack key from PEM encoded PKCS8
		return jwt.ParseRSAPublicKeyFromPEM(key)
	}
```

D vendor/github.com/dgrijalva/jwt-go/README.md => vendor/github.com/dgrijalva/jwt-go/README.md +0 -100
@@ 1,100 0,0 @@
# jwt-go

[![Build Status](https://travis-ci.org/dgrijalva/jwt-go.svg?branch=master)](https://travis-ci.org/dgrijalva/jwt-go)
[![GoDoc](https://godoc.org/github.com/dgrijalva/jwt-go?status.svg)](https://godoc.org/github.com/dgrijalva/jwt-go)

A [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html)

**NEW VERSION COMING:** There have been a lot of improvements suggested since the version 3.0.0 released in 2016. I'm working now on cutting two different releases: 3.2.0 will contain any non-breaking changes or enhancements. 4.0.0 will follow shortly which will include breaking changes. See the 4.0.0 milestone to get an idea of what's coming. If you have other ideas, or would like to participate in 4.0.0, now's the time. If you depend on this library and don't want to be interrupted, I recommend you use your dependency mangement tool to pin to version 3. 

**SECURITY NOTICE:** Some older versions of Go have a security issue in the cryotp/elliptic. Recommendation is to upgrade to at least 1.8.3. See issue #216 for more detail.

**SECURITY NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage.  See the examples provided.

## What the heck is a JWT?

JWT.io has [a great introduction](https://jwt.io/introduction) to JSON Web Tokens.

In short, it's a signed JSON object that does something useful (for example, authentication).  It's commonly used for `Bearer` tokens in Oauth 2.  A token is made of three parts, separated by `.`'s.  The first two parts are JSON objects, that have been [base64url](http://tools.ietf.org/html/rfc4648) encoded.  The last part is the signature, encoded the same way.

The first part is called the header.  It contains the necessary information for verifying the last part, the signature.  For example, which encryption method was used for signing and what key was used.

The part in the middle is the interesting bit.  It's called the Claims and contains the actual stuff you care about.  Refer to [the RFC](http://self-issued.info/docs/draft-jones-json-web-token.html) for information about reserved keys and the proper way to add your own.

## What's in the box?

This library supports the parsing and verification as well as the generation and signing of JWTs.  Current supported signing algorithms are HMAC SHA, RSA, RSA-PSS, and ECDSA, though hooks are present for adding your own.

## Examples

See [the project documentation](https://godoc.org/github.com/dgrijalva/jwt-go) for examples of usage:

* [Simple example of parsing and validating a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-Parse--Hmac)
* [Simple example of building and signing a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-New--Hmac)
* [Directory of Examples](https://godoc.org/github.com/dgrijalva/jwt-go#pkg-examples)

## Extensions

This library publishes all the necessary components for adding your own signing methods.  Simply implement the `SigningMethod` interface and register a factory method using `RegisterSigningMethod`.  

Here's an example of an extension that integrates with the Google App Engine signing tools: https://github.com/someone1/gcp-jwt-go

## Compliance

This library was last reviewed to comply with [RTF 7519](http://www.rfc-editor.org/info/rfc7519) dated May 2015 with a few notable differences:

* In order to protect against accidental use of [Unsecured JWTs](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#UnsecuredJWT), tokens using `alg=none` will only be accepted if the constant `jwt.UnsafeAllowNoneSignatureType` is provided as the key.

## Project Status & Versioning

This library is considered production ready.  Feedback and feature requests are appreciated.  The API should be considered stable.  There should be very few backwards-incompatible changes outside of major version updates (and only with good reason).

This project uses [Semantic Versioning 2.0.0](http://semver.org).  Accepted pull requests will land on `master`.  Periodically, versions will be tagged from `master`.  You can find all the releases on [the project releases page](https://github.com/dgrijalva/jwt-go/releases).

While we try to make it obvious when we make breaking changes, there isn't a great mechanism for pushing announcements out to users.  You may want to use this alternative package include: `gopkg.in/dgrijalva/jwt-go.v3`.  It will do the right thing WRT semantic versioning.

**BREAKING CHANGES:*** 
* Version 3.0.0 includes _a lot_ of changes from the 2.x line, including a few that break the API.  We've tried to break as few things as possible, so there should just be a few type signature changes.  A full list of breaking changes is available in `VERSION_HISTORY.md`.  See `MIGRATION_GUIDE.md` for more information on updating your code.

## Usage Tips

### Signing vs Encryption

A token is simply a JSON object that is signed by its author. this tells you exactly two things about the data:

* The author of the token was in the possession of the signing secret
* The data has not been modified since it was signed

It's important to know that JWT does not provide encryption, which means anyone who has access to the token can read its contents. If you need to protect (encrypt) the data, there is a companion spec, `JWE`, that provides this functionality. JWE is currently outside the scope of this library.

### Choosing a Signing Method

There are several signing methods available, and you should probably take the time to learn about the various options before choosing one.  The principal design decision is most likely going to be symmetric vs asymmetric.

Symmetric signing methods, such as HSA, use only a single secret. This is probably the simplest signing method to use since any `[]byte` can be used as a valid secret. They are also slightly computationally faster to use, though this rarely is enough to matter. Symmetric signing methods work the best when both producers and consumers of tokens are trusted, or even the same system. Since the same secret is used to both sign and validate tokens, you can't easily distribute the key for validation.

Asymmetric signing methods, such as RSA, use different keys for signing and verifying tokens. This makes it possible to produce tokens with a private key, and allow any consumer to access the public key for verification.

### Signing Methods and Key Types

Each signing method expects a different object type for its signing keys. See the package documentation for details. Here are the most common ones:

* The [HMAC signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodHMAC) (`HS256`,`HS384`,`HS512`) expect `[]byte` values for signing and validation
* The [RSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodRSA) (`RS256`,`RS384`,`RS512`) expect `*rsa.PrivateKey` for signing and `*rsa.PublicKey` for validation
* The [ECDSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodECDSA) (`ES256`,`ES384`,`ES512`) expect `*ecdsa.PrivateKey` for signing and `*ecdsa.PublicKey` for validation

### JWT and OAuth

It's worth mentioning that OAuth and JWT are not the same thing. A JWT token is simply a signed JSON object. It can be used anywhere such a thing is useful. There is some confusion, though, as JWT is the most common type of bearer token used in OAuth2 authentication.

Without going too far down the rabbit hole, here's a description of the interaction of these technologies:

* OAuth is a protocol for allowing an identity provider to be separate from the service a user is logging in to. For example, whenever you use Facebook to log into a different service (Yelp, Spotify, etc), you are using OAuth.
* OAuth defines several options for passing around authentication data. One popular method is called a "bearer token". A bearer token is simply a string that _should_ only be held by an authenticated user. Thus, simply presenting this token proves your identity. You can probably derive from here why a JWT might make a good bearer token.
* Because bearer tokens are used for authentication, it's important they're kept secret. This is why transactions that use bearer tokens typically happen over SSL.

## More

Documentation can be found [on godoc.org](http://godoc.org/github.com/dgrijalva/jwt-go).

The command line utility included in this project (cmd/jwt) provides a straightforward example of token creation and parsing as well as a useful tool for debugging your own integration. You'll also find several implementation examples in the documentation.

D vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md => vendor/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md +0 -118
@@ 1,118 0,0 @@
## `jwt-go` Version History

#### 3.2.0

* Added method `ParseUnverified` to allow users to split up the tasks of parsing and validation
* HMAC signing method returns `ErrInvalidKeyType` instead of `ErrInvalidKey` where appropriate
* Added options to `request.ParseFromRequest`, which allows for an arbitrary list of modifiers to parsing behavior. Initial set include `WithClaims` and `WithParser`. Existing usage of this function will continue to work as before.
* Deprecated `ParseFromRequestWithClaims` to simplify API in the future.

#### 3.1.0

* Improvements to `jwt` command line tool
* Added `SkipClaimsValidation` option to `Parser`
* Documentation updates

#### 3.0.0

* **Compatibility Breaking Changes**: See MIGRATION_GUIDE.md for tips on updating your code
	* Dropped support for `[]byte` keys when using RSA signing methods.  This convenience feature could contribute to security vulnerabilities involving mismatched key types with signing methods.
	* `ParseFromRequest` has been moved to `request` subpackage and usage has changed
	* The `Claims` property on `Token` is now type `Claims` instead of `map[string]interface{}`.  The default value is type `MapClaims`, which is an alias to `map[string]interface{}`.  This makes it possible to use a custom type when decoding claims.
* Other Additions and Changes
	* Added `Claims` interface type to allow users to decode the claims into a custom type
	* Added `ParseWithClaims`, which takes a third argument of type `Claims`.  Use this function instead of `Parse` if you have a custom type you'd like to decode into.
	* Dramatically improved the functionality and flexibility of `ParseFromRequest`, which is now in the `request` subpackage
	* Added `ParseFromRequestWithClaims` which is the `FromRequest` equivalent of `ParseWithClaims`
	* Added new interface type `Extractor`, which is used for extracting JWT strings from http requests.  Used with `ParseFromRequest` and `ParseFromRequestWithClaims`.
	* Added several new, more specific, validation errors to error type bitmask
	* Moved examples from README to executable example files
	* Signing method registry is now thread safe
	* Added new property to `ValidationError`, which contains the raw error returned by calls made by parse/verify (such as those returned by keyfunc or json parser)

#### 2.7.0

This will likely be the last backwards compatible release before 3.0.0, excluding essential bug fixes.

* Added new option `-show` to the `jwt` command that will just output the decoded token without verifying
* Error text for expired tokens includes how long it's been expired
* Fixed incorrect error returned from `ParseRSAPublicKeyFromPEM`
* Documentation updates

#### 2.6.0

* Exposed inner error within ValidationError
* Fixed validation errors when using UseJSONNumber flag
* Added several unit tests

#### 2.5.0

* Added support for signing method none.  You shouldn't use this.  The API tries to make this clear.
* Updated/fixed some documentation
* Added more helpful error message when trying to parse tokens that begin with `BEARER `

#### 2.4.0

* Added new type, Parser, to allow for configuration of various parsing parameters
	* You can now specify a list of valid signing methods.  Anything outside this set will be rejected.
	* You can now opt to use the `json.Number` type instead of `float64` when parsing token JSON
* Added support for [Travis CI](https://travis-ci.org/dgrijalva/jwt-go)
* Fixed some bugs with ECDSA parsing

#### 2.3.0

* Added support for ECDSA signing methods
* Added support for RSA PSS signing methods (requires go v1.4)

#### 2.2.0

* Gracefully handle a `nil` `Keyfunc` being passed to `Parse`.  Result will now be the parsed token and an error, instead of a panic.

#### 2.1.0

Backwards compatible API change that was missed in 2.0.0.

* The `SignedString` method on `Token` now takes `interface{}` instead of `[]byte`

#### 2.0.0

There were two major reasons for breaking backwards compatibility with this update.  The first was a refactor required to expand the width of the RSA and HMAC-SHA signing implementations.  There will likely be no required code changes to support this change.

The second update, while unfortunately requiring a small change in integration, is required to open up this library to other signing methods.  Not all keys used for all signing methods have a single standard on-disk representation.  Requiring `[]byte` as the type for all keys proved too limiting.  Additionally, this implementation allows for pre-parsed tokens to be reused, which might matter in an application that parses a high volume of tokens with a small set of keys.  Backwards compatibilty has been maintained for passing `[]byte` to the RSA signing methods, but they will also accept `*rsa.PublicKey` and `*rsa.PrivateKey`.

It is likely the only integration change required here will be to change `func(t *jwt.Token) ([]byte, error)` to `func(t *jwt.Token) (interface{}, error)` when calling `Parse`.

* **Compatibility Breaking Changes**
	* `SigningMethodHS256` is now `*SigningMethodHMAC` instead of `type struct`
	* `SigningMethodRS256` is now `*SigningMethodRSA` instead of `type struct`
	* `KeyFunc` now returns `interface{}` instead of `[]byte`
	* `SigningMethod.Sign` now takes `interface{}` instead of `[]byte` for the key
	* `SigningMethod.Verify` now takes `interface{}` instead of `[]byte` for the key
* Renamed type `SigningMethodHS256` to `SigningMethodHMAC`.  Specific sizes are now just instances of this type.
    * Added public package global `SigningMethodHS256`
    * Added public package global `SigningMethodHS384`
    * Added public package global `SigningMethodHS512`
* Renamed type `SigningMethodRS256` to `SigningMethodRSA`.  Specific sizes are now just instances of this type.
    * Added public package global `SigningMethodRS256`
    * Added public package global `SigningMethodRS384`
    * Added public package global `SigningMethodRS512`
* Moved sample private key for HMAC tests from an inline value to a file on disk.  Value is unchanged.
* Refactored the RSA implementation to be easier to read
* Exposed helper methods `ParseRSAPrivateKeyFromPEM` and `ParseRSAPublicKeyFromPEM`

#### 1.0.2

* Fixed bug in parsing public keys from certificates
* Added more tests around the parsing of keys for RS256
* Code refactoring in RS256 implementation.  No functional changes

#### 1.0.1

* Fixed panic if RS256 signing method was passed an invalid key

#### 1.0.0

* First versioned release
* API stabilized
* Supports creating, signing, parsing, and validating JWT tokens
* Supports RS256 and HS256 signing methods
\ No newline at end of file

D vendor/github.com/dgrijalva/jwt-go/claims.go => vendor/github.com/dgrijalva/jwt-go/claims.go +0 -134
@@ 1,134 0,0 @@
package jwt

import (
	"crypto/subtle"
	"fmt"
	"time"
)

// For a type to be a Claims object, it must just have a Valid method that determines
// if the token is invalid for any supported reason
type Claims interface {
	Valid() error
}

// Structured version of Claims Section, as referenced at
// https://tools.ietf.org/html/rfc7519#section-4.1
// See examples for how to use this with your own claim types
type StandardClaims struct {
	Audience  string `json:"aud,omitempty"`
	ExpiresAt int64  `json:"exp,omitempty"`
	Id        string `json:"jti,omitempty"`
	IssuedAt  int64  `json:"iat,omitempty"`
	Issuer    string `json:"iss,omitempty"`
	NotBefore int64  `json:"nbf,omitempty"`
	Subject   string `json:"sub,omitempty"`
}

// Validates time based claims "exp, iat, nbf".
// There is no accounting for clock skew.
// As well, if any of the above claims are not in the token, it will still
// be considered a valid claim.
func (c StandardClaims) Valid() error {
	vErr := new(ValidationError)
	now := TimeFunc().Unix()

	// The claims below are optional, by default, so if they are set to the
	// default value in Go, let's not fail the verification for them.
	if c.VerifyExpiresAt(now, false) == false {
		delta := time.Unix(now, 0).Sub(time.Unix(c.ExpiresAt, 0))
		vErr.Inner = fmt.Errorf("token is expired by %v", delta)
		vErr.Errors |= ValidationErrorExpired
	}

	if c.VerifyIssuedAt(now, false) == false {
		vErr.Inner = fmt.Errorf("Token used before issued")
		vErr.Errors |= ValidationErrorIssuedAt
	}

	if c.VerifyNotBefore(now, false) == false {
		vErr.Inner = fmt.Errorf("token is not valid yet")
		vErr.Errors |= ValidationErrorNotValidYet
	}

	if vErr.valid() {
		return nil
	}

	return vErr
}

// Compares the aud claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (c *StandardClaims) VerifyAudience(cmp string, req bool) bool {
	return verifyAud(c.Audience, cmp, req)
}

// Compares the exp claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool) bool {
	return verifyExp(c.ExpiresAt, cmp, req)
}

// Compares the iat claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (c *StandardClaims) VerifyIssuedAt(cmp int64, req bool) bool {
	return verifyIat(c.IssuedAt, cmp, req)
}

// Compares the iss claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (c *StandardClaims) VerifyIssuer(cmp string, req bool) bool {
	return verifyIss(c.Issuer, cmp, req)
}

// Compares the nbf claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool {
	return verifyNbf(c.NotBefore, cmp, req)
}

// ----- helpers

func verifyAud(aud string, cmp string, required bool) bool {
	if aud == "" {
		return !required
	}
	if subtle.ConstantTimeCompare([]byte(aud), []byte(cmp)) != 0 {
		return true
	} else {
		return false
	}
}

func verifyExp(exp int64, now int64, required bool) bool {
	if exp == 0 {
		return !required
	}
	return now <= exp
}

func verifyIat(iat int64, now int64, required bool) bool {
	if iat == 0 {
		return !required
	}
	return now >= iat
}

func verifyIss(iss string, cmp string, required bool) bool {
	if iss == "" {
		return !required
	}
	if subtle.ConstantTimeCompare([]byte(iss), []byte(cmp)) != 0 {
		return true
	} else {
		return false
	}
}

func verifyNbf(nbf int64, now int64, required bool) bool {
	if nbf == 0 {
		return !required
	}
	return now >= nbf
}

D vendor/github.com/dgrijalva/jwt-go/doc.go => vendor/github.com/dgrijalva/jwt-go/doc.go +0 -4
@@ 1,4 0,0 @@
// Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html
//
// See README.md for more info.
package jwt

D vendor/github.com/dgrijalva/jwt-go/ecdsa.go => vendor/github.com/dgrijalva/jwt-go/ecdsa.go +0 -148
@@ 1,148 0,0 @@
package jwt

import (
	"crypto"
	"crypto/ecdsa"
	"crypto/rand"
	"errors"
	"math/big"
)

var (
	// Sadly this is missing from crypto/ecdsa compared to crypto/rsa
	ErrECDSAVerification = errors.New("crypto/ecdsa: verification error")
)

// Implements the ECDSA family of signing methods signing methods
// Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification
type SigningMethodECDSA struct {
	Name      string
	Hash      crypto.Hash
	KeySize   int
	CurveBits int
}

// Specific instances for EC256 and company
var (
	SigningMethodES256 *SigningMethodECDSA
	SigningMethodES384 *SigningMethodECDSA
	SigningMethodES512 *SigningMethodECDSA
)

func init() {
	// ES256
	SigningMethodES256 = &SigningMethodECDSA{"ES256", crypto.SHA256, 32, 256}
	RegisterSigningMethod(SigningMethodES256.Alg(), func() SigningMethod {
		return SigningMethodES256
	})

	// ES384
	SigningMethodES384 = &SigningMethodECDSA{"ES384", crypto.SHA384, 48, 384}
	RegisterSigningMethod(SigningMethodES384.Alg(), func() SigningMethod {
		return SigningMethodES384
	})

	// ES512
	SigningMethodES512 = &SigningMethodECDSA{"ES512", crypto.SHA512, 66, 521}
	RegisterSigningMethod(SigningMethodES512.Alg(), func() SigningMethod {
		return SigningMethodES512
	})
}

func (m *SigningMethodECDSA) Alg() string {
	return m.Name
}

// Implements the Verify method from SigningMethod
// For this verify method, key must be an ecdsa.PublicKey struct
func (m *SigningMethodECDSA) Verify(signingString, signature string, key interface{}) error {
	var err error

	// Decode the signature
	var sig []byte
	if sig, err = DecodeSegment(signature); err != nil {
		return err
	}

	// Get the key
	var ecdsaKey *ecdsa.PublicKey
	switch k := key.(type) {
	case *ecdsa.PublicKey:
		ecdsaKey = k
	default:
		return ErrInvalidKeyType
	}

	if len(sig) != 2*m.KeySize {
		return ErrECDSAVerification
	}

	r := big.NewInt(0).SetBytes(sig[:m.KeySize])
	s := big.NewInt(0).SetBytes(sig[m.KeySize:])

	// Create hasher
	if !m.Hash.Available() {
		return ErrHashUnavailable
	}
	hasher := m.Hash.New()
	hasher.Write([]byte(signingString))

	// Verify the signature
	if verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus == true {
		return nil
	} else {
		return ErrECDSAVerification
	}
}

// Implements the Sign method from SigningMethod
// For this signing method, key must be an ecdsa.PrivateKey struct
func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) (string, error) {
	// Get the key
	var ecdsaKey *ecdsa.PrivateKey
	switch k := key.(type) {
	case *ecdsa.PrivateKey:
		ecdsaKey = k
	default:
		return "", ErrInvalidKeyType
	}

	// Create the hasher
	if !m.Hash.Available() {
		return "", ErrHashUnavailable
	}

	hasher := m.Hash.New()
	hasher.Write([]byte(signingString))

	// Sign the string and return r, s
	if r, s, err := ecdsa.Sign(rand.Reader, ecdsaKey, hasher.Sum(nil)); err == nil {
		curveBits := ecdsaKey.Curve.Params().BitSize

		if m.CurveBits != curveBits {
			return "", ErrInvalidKey
		}

		keyBytes := curveBits / 8
		if curveBits%8 > 0 {
			keyBytes += 1
		}

		// We serialize the outpus (r and s) into big-endian byte arrays and pad
		// them with zeros on the left to make sure the sizes work out. Both arrays
		// must be keyBytes long, and the output must be 2*keyBytes long.
		rBytes := r.Bytes()
		rBytesPadded := make([]byte, keyBytes)
		copy(rBytesPadded[keyBytes-len(rBytes):], rBytes)

		sBytes := s.Bytes()
		sBytesPadded := make([]byte, keyBytes)
		copy(sBytesPadded[keyBytes-len(sBytes):], sBytes)

		out := append(rBytesPadded, sBytesPadded...)

		return EncodeSegment(out), nil
	} else {
		return "", err
	}
}

D vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go => vendor/github.com/dgrijalva/jwt-go/ecdsa_utils.go +0 -67
@@ 1,67 0,0 @@
package jwt

import (
	"crypto/ecdsa"
	"crypto/x509"
	"encoding/pem"
	"errors"
)

var (
	ErrNotECPublicKey  = errors.New("Key is not a valid ECDSA public key")
	ErrNotECPrivateKey = errors.New("Key is not a valid ECDSA private key")
)

// Parse PEM encoded Elliptic Curve Private Key Structure
func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {
	var err error

	// Parse PEM block
	var block *pem.Block
	if block, _ = pem.Decode(key); block == nil {
		return nil, ErrKeyMustBePEMEncoded
	}

	// Parse the key
	var parsedKey interface{}
	if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil {
		return nil, err
	}

	var pkey *ecdsa.PrivateKey
	var ok bool
	if pkey, ok = parsedKey.(*ecdsa.PrivateKey); !ok {
		return nil, ErrNotECPrivateKey
	}

	return pkey, nil
}

// Parse PEM encoded PKCS1 or PKCS8 public key
func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) {
	var err error

	// Parse PEM block
	var block *pem.Block
	if block, _ = pem.Decode(key); block == nil {
		return nil, ErrKeyMustBePEMEncoded
	}

	// Parse the key
	var parsedKey interface{}
	if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
		if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
			parsedKey = cert.PublicKey
		} else {
			return nil, err
		}
	}

	var pkey *ecdsa.PublicKey
	var ok bool
	if pkey, ok = parsedKey.(*ecdsa.PublicKey); !ok {
		return nil, ErrNotECPublicKey
	}

	return pkey, nil
}

D vendor/github.com/dgrijalva/jwt-go/errors.go => vendor/github.com/dgrijalva/jwt-go/errors.go +0 -59
@@ 1,59 0,0 @@
package jwt

import (
	"errors"
)

// Error constants
var (
	ErrInvalidKey      = errors.New("key is invalid")
	ErrInvalidKeyType  = errors.New("key is of invalid type")
	ErrHashUnavailable = errors.New("the requested hash function is unavailable")
)

// The errors that might occur when parsing and validating a token
const (
	ValidationErrorMalformed        uint32 = 1 << iota // Token is malformed
	ValidationErrorUnverifiable                        // Token could not be verified because of signing problems
	ValidationErrorSignatureInvalid                    // Signature validation failed

	// Standard Claim validation errors
	ValidationErrorAudience      // AUD validation failed
	ValidationErrorExpired       // EXP validation failed
	ValidationErrorIssuedAt      // IAT validation failed
	ValidationErrorIssuer        // ISS validation failed
	ValidationErrorNotValidYet   // NBF validation failed
	ValidationErrorId            // JTI validation failed
	ValidationErrorClaimsInvalid // Generic claims validation error
)

// Helper for constructing a ValidationError with a string error message
func NewValidationError(errorText string, errorFlags uint32) *ValidationError {
	return &ValidationError{
		text:   errorText,
		Errors: errorFlags,
	}
}

// The error from Parse if token is not valid
type ValidationError struct {
	Inner  error  // stores the error returned by external dependencies, i.e.: KeyFunc
	Errors uint32 // bitfield.  see ValidationError... constants
	text   string // errors that do not have a valid error just have text
}

// Validation error is an error type
func (e ValidationError) Error() string {
	if e.Inner != nil {
		return e.Inner.Error()
	} else if e.text != "" {
		return e.text
	} else {
		return "token is invalid"
	}
}

// No errors
func (e *ValidationError) valid() bool {
	return e.Errors == 0
}

D vendor/github.com/dgrijalva/jwt-go/hmac.go => vendor/github.com/dgrijalva/jwt-go/hmac.go +0 -95
@@ 1,95 0,0 @@
package jwt

import (
	"crypto"
	"crypto/hmac"
	"errors"
)

// Implements the HMAC-SHA family of signing methods signing methods
// Expects key type of []byte for both signing and validation
type SigningMethodHMAC struct {
	Name string
	Hash crypto.Hash
}

// Specific instances for HS256 and company
var (
	SigningMethodHS256  *SigningMethodHMAC
	SigningMethodHS384  *SigningMethodHMAC
	SigningMethodHS512  *SigningMethodHMAC
	ErrSignatureInvalid = errors.New("signature is invalid")
)

func init() {
	// HS256
	SigningMethodHS256 = &SigningMethodHMAC{"HS256", crypto.SHA256}
	RegisterSigningMethod(SigningMethodHS256.Alg(), func() SigningMethod {
		return SigningMethodHS256
	})

	// HS384
	SigningMethodHS384 = &SigningMethodHMAC{"HS384", crypto.SHA384}
	RegisterSigningMethod(SigningMethodHS384.Alg(), func() SigningMethod {
		return SigningMethodHS384
	})

	// HS512
	SigningMethodHS512 = &SigningMethodHMAC{"HS512", crypto.SHA512}
	RegisterSigningMethod(SigningMethodHS512.Alg(), func() SigningMethod {
		return SigningMethodHS512
	})
}

func (m *SigningMethodHMAC) Alg() string {
	return m.Name
}

// Verify the signature of HSXXX tokens.  Returns nil if the signature is valid.
func (m *SigningMethodHMAC) Verify(signingString, signature string, key interface{}) error {
	// Verify the key is the right type
	keyBytes, ok := key.([]byte)
	if !ok {
		return ErrInvalidKeyType
	}

	// Decode signature, for comparison
	sig, err := DecodeSegment(signature)
	if err != nil {
		return err
	}

	// Can we use the specified hashing method?
	if !m.Hash.Available() {
		return ErrHashUnavailable
	}

	// This signing method is symmetric, so we validate the signature
	// by reproducing the signature from the signing string and key, then
	// comparing that against the provided signature.
	hasher := hmac.New(m.Hash.New, keyBytes)
	hasher.Write([]byte(signingString))
	if !hmac.Equal(sig, hasher.Sum(nil)) {
		return ErrSignatureInvalid
	}

	// No validation errors.  Signature is good.
	return nil
}

// Implements the Sign method from SigningMethod for this signing method.
// Key must be []byte
func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) (string, error) {
	if keyBytes, ok := key.([]byte); ok {
		if !m.Hash.Available() {
			return "", ErrHashUnavailable
		}

		hasher := hmac.New(m.Hash.New, keyBytes)
		hasher.Write([]byte(signingString))

		return EncodeSegment(hasher.Sum(nil)), nil
	}

	return "", ErrInvalidKeyType
}

D vendor/github.com/dgrijalva/jwt-go/map_claims.go => vendor/github.com/dgrijalva/jwt-go/map_claims.go +0 -94
@@ 1,94 0,0 @@
package jwt

import (
	"encoding/json"
	"errors"
	// "fmt"
)

// Claims type that uses the map[string]interface{} for JSON decoding
// This is the default claims type if you don't supply one
type MapClaims map[string]interface{}

// Compares the aud claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (m MapClaims) VerifyAudience(cmp string, req bool) bool {
	aud, _ := m["aud"].(string)
	return verifyAud(aud, cmp, req)
}

// Compares the exp claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool {
	switch exp := m["exp"].(type) {
	case float64:
		return verifyExp(int64(exp), cmp, req)
	case json.Number:
		v, _ := exp.Int64()
		return verifyExp(v, cmp, req)
	}
	return req == false
}

// Compares the iat claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool {
	switch iat := m["iat"].(type) {
	case float64:
		return verifyIat(int64(iat), cmp, req)
	case json.Number:
		v, _ := iat.Int64()
		return verifyIat(v, cmp, req)
	}
	return req == false
}

// Compares the iss claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (m MapClaims) VerifyIssuer(cmp string, req bool) bool {
	iss, _ := m["iss"].(string)
	return verifyIss(iss, cmp, req)
}

// Compares the nbf claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool {
	switch nbf := m["nbf"].(type) {
	case float64:
		return verifyNbf(int64(nbf), cmp, req)
	case json.Number:
		v, _ := nbf.Int64()
		return verifyNbf(v, cmp, req)
	}
	return req == false
}

// Validates time based claims "exp, iat, nbf".
// There is no accounting for clock skew.
// As well, if any of the above claims are not in the token, it will still
// be considered a valid claim.
func (m MapClaims) Valid() error {
	vErr := new(ValidationError)
	now := TimeFunc().Unix()

	if m.VerifyExpiresAt(now, false) == false {
		vErr.Inner = errors.New("Token is expired")
		vErr.Errors |= ValidationErrorExpired
	}

	if m.VerifyIssuedAt(now, false) == false {
		vErr.Inner = errors.New("Token used before issued")
		vErr.Errors |= ValidationErrorIssuedAt
	}

	if m.VerifyNotBefore(now, false) == false {
		vErr.Inner = errors.New("Token is not valid yet")
		vErr.Errors |= ValidationErrorNotValidYet
	}

	if vErr.valid() {
		return nil
	}

	return vErr
}

D vendor/github.com/dgrijalva/jwt-go/none.go => vendor/github.com/dgrijalva/jwt-go/none.go +0 -52
@@ 1,52 0,0 @@
package jwt

// Implements the none signing method.  This is required by the spec
// but you probably should never use it.
var SigningMethodNone *signingMethodNone

const UnsafeAllowNoneSignatureType unsafeNoneMagicConstant = "none signing method allowed"

var NoneSignatureTypeDisallowedError error

type signingMethodNone struct{}
type unsafeNoneMagicConstant string