TUN-8333: Bump go-jose dependency to v4

This commit is contained in:
Devin Carr 2024-04-03 13:19:12 -07:00
parent a1a9f3813e
commit 687682120c
113 changed files with 1540 additions and 709 deletions

15
go.mod
View File

@ -4,14 +4,15 @@ go 1.21
require ( require (
github.com/coredns/coredns v1.10.0 github.com/coredns/coredns v1.10.0
github.com/coreos/go-oidc/v3 v3.6.0 github.com/coreos/go-oidc/v3 v3.10.0
github.com/coreos/go-systemd/v22 v22.5.0 github.com/coreos/go-systemd/v22 v22.5.0
github.com/facebookgo/grace v0.0.0-20180706040059-75cf19382434 github.com/facebookgo/grace v0.0.0-20180706040059-75cf19382434
github.com/fortytw2/leaktest v1.3.0
github.com/fsnotify/fsnotify v1.4.9 github.com/fsnotify/fsnotify v1.4.9
github.com/getsentry/sentry-go v0.16.0 github.com/getsentry/sentry-go v0.16.0
github.com/go-chi/chi/v5 v5.0.8 github.com/go-chi/chi/v5 v5.0.8
github.com/go-chi/cors v1.2.1 github.com/go-chi/cors v1.2.1
github.com/go-jose/go-jose/v3 v3.0.0 github.com/go-jose/go-jose/v4 v4.0.1
github.com/gobwas/ws v1.0.4 github.com/gobwas/ws v1.0.4
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3
github.com/google/gopacket v1.1.19 github.com/google/gopacket v1.1.19
@ -35,11 +36,11 @@ require (
go.opentelemetry.io/otel/trace v1.21.0 go.opentelemetry.io/otel/trace v1.21.0
go.opentelemetry.io/proto/otlp v1.0.0 go.opentelemetry.io/proto/otlp v1.0.0
go.uber.org/automaxprocs v1.4.0 go.uber.org/automaxprocs v1.4.0
golang.org/x/crypto v0.16.0 golang.org/x/crypto v0.21.0
golang.org/x/net v0.19.0 golang.org/x/net v0.21.0
golang.org/x/sync v0.4.0 golang.org/x/sync v0.4.0
golang.org/x/sys v0.15.0 golang.org/x/sys v0.18.0
golang.org/x/term v0.15.0 golang.org/x/term v0.18.0
google.golang.org/protobuf v1.31.0 google.golang.org/protobuf v1.31.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0 gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
@ -60,7 +61,6 @@ require (
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 // indirect github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 // indirect
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
github.com/fortytw2/leaktest v1.3.0 // indirect
github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/logr v1.3.0 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
@ -82,7 +82,6 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
go.opentelemetry.io/otel/metric v1.21.0 // indirect go.opentelemetry.io/otel/metric v1.21.0 // indirect
go.uber.org/mock v0.3.0 // indirect go.uber.org/mock v0.3.0 // indirect

29
go.sum
View File

@ -60,8 +60,8 @@ github.com/coredns/caddy v1.1.1 h1:2eYKZT7i6yxIfGP3qLJoJ7HAsDJqYB+X68g4NYjSrE0=
github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4=
github.com/coredns/coredns v1.10.0 h1:jCfuWsBjTs0dapkkhISfPCzn5LqvSRtrFtaf/Tjj4DI= github.com/coredns/coredns v1.10.0 h1:jCfuWsBjTs0dapkkhISfPCzn5LqvSRtrFtaf/Tjj4DI=
github.com/coredns/coredns v1.10.0/go.mod h1:CIfRU5TgpuoIiJBJ4XrofQzfFQpPFh32ERpUevrSlaw= github.com/coredns/coredns v1.10.0/go.mod h1:CIfRU5TgpuoIiJBJ4XrofQzfFQpPFh32ERpUevrSlaw=
github.com/coreos/go-oidc/v3 v3.6.0 h1:AKVxfYw1Gmkn/w96z0DbT/B/xFnzTd3MkZvWLjF4n/o= github.com/coreos/go-oidc/v3 v3.10.0 h1:tDnXHnLyiTVyT/2zLDGj09pFPkhND8Gl8lnTRhoEaJU=
github.com/coreos/go-oidc/v3 v3.6.0/go.mod h1:ZpHUsHBucTUj6WOkrP4E20UPynbLZzhTQ1XKCXkxyPc= github.com/coreos/go-oidc/v3 v3.10.0/go.mod h1:5j11xcw0D3+SGxn6Z/WFADsgcWVMyNAlSQupk0KK3ac=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
@ -108,8 +108,8 @@ github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U=
github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
@ -322,10 +322,6 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs=
github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
github.com/quic-go/quic-go v0.40.1-0.20231203135336-87ef8ec48d55 h1:I4N3ZRnkZPbDN935Tg8QDf8fRpHp3bZ0U0/L42jBgNE=
github.com/quic-go/quic-go v0.40.1-0.20231203135336-87ef8ec48d55/go.mod h1:PeN7kuVJ4xZbxSv/4OX6S1USOX8MJvydwpTx31vx60c=
github.com/quic-go/quic-go v0.40.1-0.20240101045026-22b7f7744eb6 h1:OI4WiysowCcxLtcZMGBZildo12di3ljcMN4vWdUQpoU= github.com/quic-go/quic-go v0.40.1-0.20240101045026-22b7f7744eb6 h1:OI4WiysowCcxLtcZMGBZildo12di3ljcMN4vWdUQpoU=
github.com/quic-go/quic-go v0.40.1-0.20240101045026-22b7f7744eb6/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA= github.com/quic-go/quic-go v0.40.1-0.20240101045026-22b7f7744eb6/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@ -391,12 +387,11 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -468,8 +463,8 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -538,12 +533,12 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@ -3,7 +3,8 @@ package management
import ( import (
"fmt" "fmt"
"github.com/go-jose/go-jose/v3/jwt" "github.com/go-jose/go-jose/v4"
"github.com/go-jose/go-jose/v4/jwt"
) )
type managementTokenClaims struct { type managementTokenClaims struct {
@ -37,7 +38,7 @@ func (t *actor) verify() bool {
} }
func parseToken(token string) (*managementTokenClaims, error) { func parseToken(token string) (*managementTokenClaims, error) {
jwt, err := jwt.ParseSigned(token) jwt, err := jwt.ParseSigned(token, []jose.SignatureAlgorithm{jose.ES256})
if err != nil { if err != nil {
return nil, fmt.Errorf("malformed jwt: %v", err) return nil, fmt.Errorf("malformed jwt: %v", err)
} }

View File

@ -7,7 +7,7 @@ import (
"errors" "errors"
"testing" "testing"
"github.com/go-jose/go-jose/v3" "github.com/go-jose/go-jose/v4"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )

View File

@ -15,7 +15,8 @@ import (
"os" "os"
"time" "time"
"github.com/go-jose/go-jose/v3/jwt" "github.com/go-jose/go-jose/v4"
"github.com/go-jose/go-jose/v4/jwt"
homedir "github.com/mitchellh/go-homedir" homedir "github.com/mitchellh/go-homedir"
"github.com/pkg/errors" "github.com/pkg/errors"
gossh "golang.org/x/crypto/ssh" gossh "golang.org/x/crypto/ssh"
@ -51,6 +52,8 @@ type errorResponse struct {
var mockRequest func(url, contentType string, body io.Reader) (*http.Response, error) = nil var mockRequest func(url, contentType string, body io.Reader) (*http.Response, error) = nil
var signatureAlgs = []jose.SignatureAlgorithm{jose.RS256}
// GenerateShortLivedCertificate generates and stores a keypair for short lived certs // GenerateShortLivedCertificate generates and stores a keypair for short lived certs
func GenerateShortLivedCertificate(appURL *url.URL, token string) error { func GenerateShortLivedCertificate(appURL *url.URL, token string) error {
fullName, err := cfpath.GenerateSSHCertFilePathFromURL(appURL, keyName) fullName, err := cfpath.GenerateSSHCertFilePathFromURL(appURL, keyName)
@ -87,7 +90,7 @@ func SignCert(token, pubKey string) (string, error) {
return "", errors.New("invalid token") return "", errors.New("invalid token")
} }
parsedToken, err := jwt.ParseSigned(token) parsedToken, err := jwt.ParseSigned(token, signatureAlgs)
if err != nil { if err != nil {
return "", errors.Wrap(err, "failed to parse JWT") return "", errors.Wrap(err, "failed to parse JWT")
} }

View File

@ -3,6 +3,8 @@
package sshgen package sshgen
import ( import (
"crypto/rand"
"crypto/rsa"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@ -14,8 +16,8 @@ import (
"testing" "testing"
"time" "time"
"github.com/go-jose/go-jose/v3" "github.com/go-jose/go-jose/v4"
"github.com/go-jose/go-jose/v3/jwt" "github.com/go-jose/go-jose/v4/jwt"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/cloudflare/cloudflared/config" "github.com/cloudflare/cloudflared/config"
@ -103,13 +105,16 @@ func tokenGenerator() string {
Expiry: jwt.NewNumericDate(exp), Expiry: jwt.NewNumericDate(exp),
} }
key := []byte("secret") key, err := rsa.GenerateKey(rand.Reader, 4096)
signer, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: key}, (&jose.SignerOptions{}).WithType("JWT")) if err != nil {
panic(err)
}
signer, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.RS256, Key: key}, (&jose.SignerOptions{}).WithType("JWT"))
if err != nil { if err != nil {
panic(err) panic(err)
} }
signedToken, err := jwt.Signed(signer).Claims(claims).CompactSerialize() signedToken, err := jwt.Signed(signer).Claims(claims).Serialize()
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -12,7 +12,7 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/go-jose/go-jose/v3" "github.com/go-jose/go-jose/v4"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/rs/zerolog" "github.com/rs/zerolog"
@ -32,6 +32,7 @@ const (
var ( var (
userAgent = "DEV" userAgent = "DEV"
signatureAlgs = []jose.SignatureAlgorithm{jose.RS256}
) )
type AppInfo struct { type AppInfo struct {
@ -415,7 +416,7 @@ func getTokenIfExists(path string) (*jose.JSONWebSignature, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
token, err := jose.ParseSigned(string(content)) token, err := jose.ParseSigned(string(content), signatureAlgs)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -1,5 +1,7 @@
package oidc package oidc
import jose "github.com/go-jose/go-jose/v4"
// JOSE asymmetric signing algorithm values as defined by RFC 7518 // JOSE asymmetric signing algorithm values as defined by RFC 7518
// //
// see: https://tools.ietf.org/html/rfc7518#section-3.1 // see: https://tools.ietf.org/html/rfc7518#section-3.1
@ -15,3 +17,16 @@ const (
PS512 = "PS512" // RSASSA-PSS using SHA512 and MGF1-SHA512 PS512 = "PS512" // RSASSA-PSS using SHA512 and MGF1-SHA512
EdDSA = "EdDSA" // Ed25519 using SHA-512 EdDSA = "EdDSA" // Ed25519 using SHA-512
) )
var allAlgs = []jose.SignatureAlgorithm{
jose.RS256,
jose.RS384,
jose.RS512,
jose.ES256,
jose.ES384,
jose.ES512,
jose.PS256,
jose.PS384,
jose.PS512,
jose.EdDSA,
}

View File

@ -8,12 +8,12 @@ import (
"crypto/rsa" "crypto/rsa"
"errors" "errors"
"fmt" "fmt"
"io/ioutil" "io"
"net/http" "net/http"
"sync" "sync"
"time" "time"
jose "github.com/go-jose/go-jose/v3" jose "github.com/go-jose/go-jose/v4"
) )
// StaticKeySet is a verifier that validates JWT against a static set of public keys. // StaticKeySet is a verifier that validates JWT against a static set of public keys.
@ -25,7 +25,9 @@ type StaticKeySet struct {
// VerifySignature compares the signature against a static set of public keys. // VerifySignature compares the signature against a static set of public keys.
func (s *StaticKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, error) { func (s *StaticKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, error) {
jws, err := jose.ParseSigned(jwt) // Algorithms are already checked by Verifier, so this parse method accepts
// any algorithm.
jws, err := jose.ParseSigned(jwt, allAlgs)
if err != nil { if err != nil {
return nil, fmt.Errorf("parsing jwt: %v", err) return nil, fmt.Errorf("parsing jwt: %v", err)
} }
@ -127,8 +129,13 @@ var parsedJWTKey contextKey
func (r *RemoteKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, error) { func (r *RemoteKeySet) VerifySignature(ctx context.Context, jwt string) ([]byte, error) {
jws, ok := ctx.Value(parsedJWTKey).(*jose.JSONWebSignature) jws, ok := ctx.Value(parsedJWTKey).(*jose.JSONWebSignature)
if !ok { if !ok {
// The algorithm values are already enforced by the Validator, which also sets
// the context value above to pre-parsed signature.
//
// Practically, this codepath isn't called in normal use of this package, but
// if it is, the algorithms have already been checked.
var err error var err error
jws, err = jose.ParseSigned(jwt) jws, err = jose.ParseSigned(jwt, allAlgs)
if err != nil { if err != nil {
return nil, fmt.Errorf("oidc: malformed jwt: %v", err) return nil, fmt.Errorf("oidc: malformed jwt: %v", err)
} }
@ -159,7 +166,7 @@ func (r *RemoteKeySet) verify(ctx context.Context, jws *jose.JSONWebSignature) (
// https://openid.net/specs/openid-connect-core-1_0.html#RotateSigKeys // https://openid.net/specs/openid-connect-core-1_0.html#RotateSigKeys
keys, err := r.keysFromRemote(ctx) keys, err := r.keysFromRemote(ctx)
if err != nil { if err != nil {
return nil, fmt.Errorf("fetching keys %v", err) return nil, fmt.Errorf("fetching keys %w", err)
} }
for _, key := range keys { for _, key := range keys {
@ -228,11 +235,11 @@ func (r *RemoteKeySet) updateKeys() ([]jose.JSONWebKey, error) {
resp, err := doRequest(r.ctx, req) resp, err := doRequest(r.ctx, req)
if err != nil { if err != nil {
return nil, fmt.Errorf("oidc: get keys failed %v", err) return nil, fmt.Errorf("oidc: get keys failed %w", err)
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) body, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to read response body: %v", err) return nil, fmt.Errorf("unable to read response body: %v", err)
} }

View File

@ -10,7 +10,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"hash" "hash"
"io/ioutil" "io"
"mime" "mime"
"net/http" "net/http"
"strings" "strings"
@ -79,7 +79,7 @@ func getClient(ctx context.Context) *http.Client {
// provider, err := oidc.NewProvider(ctx, discoveryBaseURL) // provider, err := oidc.NewProvider(ctx, discoveryBaseURL)
// //
// This is insecure because validating the correct issuer is critical for multi-tenant // This is insecure because validating the correct issuer is critical for multi-tenant
// proivders. Any overrides here MUST be carefully reviewed. // providers. Any overrides here MUST be carefully reviewed.
func InsecureIssuerURLContext(ctx context.Context, issuerURL string) context.Context { func InsecureIssuerURLContext(ctx context.Context, issuerURL string) context.Context {
return context.WithValue(ctx, issuerURLKey, issuerURL) return context.WithValue(ctx, issuerURLKey, issuerURL)
} }
@ -97,6 +97,7 @@ type Provider struct {
issuer string issuer string
authURL string authURL string
tokenURL string tokenURL string
deviceAuthURL string
userInfoURL string userInfoURL string
jwksURL string jwksURL string
algorithms []string algorithms []string
@ -131,6 +132,7 @@ type providerJSON struct {
Issuer string `json:"issuer"` Issuer string `json:"issuer"`
AuthURL string `json:"authorization_endpoint"` AuthURL string `json:"authorization_endpoint"`
TokenURL string `json:"token_endpoint"` TokenURL string `json:"token_endpoint"`
DeviceAuthURL string `json:"device_authorization_endpoint"`
JWKSURL string `json:"jwks_uri"` JWKSURL string `json:"jwks_uri"`
UserInfoURL string `json:"userinfo_endpoint"` UserInfoURL string `json:"userinfo_endpoint"`
Algorithms []string `json:"id_token_signing_alg_values_supported"` Algorithms []string `json:"id_token_signing_alg_values_supported"`
@ -165,6 +167,9 @@ type ProviderConfig struct {
// TokenURL is the endpoint used by the provider to support the OAuth 2.0 // TokenURL is the endpoint used by the provider to support the OAuth 2.0
// token endpoint. // token endpoint.
TokenURL string TokenURL string
// DeviceAuthURL is the endpoint used by the provider to support the OAuth 2.0
// device authorization endpoint.
DeviceAuthURL string
// UserInfoURL is the endpoint used by the provider to support the OpenID // UserInfoURL is the endpoint used by the provider to support the OpenID
// Connect UserInfo flow. // Connect UserInfo flow.
// //
@ -188,6 +193,7 @@ func (p *ProviderConfig) NewProvider(ctx context.Context) *Provider {
issuer: p.IssuerURL, issuer: p.IssuerURL,
authURL: p.AuthURL, authURL: p.AuthURL,
tokenURL: p.TokenURL, tokenURL: p.TokenURL,
deviceAuthURL: p.DeviceAuthURL,
userInfoURL: p.UserInfoURL, userInfoURL: p.UserInfoURL,
jwksURL: p.JWKSURL, jwksURL: p.JWKSURL,
algorithms: p.Algorithms, algorithms: p.Algorithms,
@ -211,7 +217,7 @@ func NewProvider(ctx context.Context, issuer string) (*Provider, error) {
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) body, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to read response body: %v", err) return nil, fmt.Errorf("unable to read response body: %v", err)
} }
@ -243,6 +249,7 @@ func NewProvider(ctx context.Context, issuer string) (*Provider, error) {
issuer: issuerURL, issuer: issuerURL,
authURL: p.AuthURL, authURL: p.AuthURL,
tokenURL: p.TokenURL, tokenURL: p.TokenURL,
deviceAuthURL: p.DeviceAuthURL,
userInfoURL: p.UserInfoURL, userInfoURL: p.UserInfoURL,
jwksURL: p.JWKSURL, jwksURL: p.JWKSURL,
algorithms: algs, algorithms: algs,
@ -273,7 +280,7 @@ func (p *Provider) Claims(v interface{}) error {
// Endpoint returns the OAuth2 auth and token endpoints for the given provider. // Endpoint returns the OAuth2 auth and token endpoints for the given provider.
func (p *Provider) Endpoint() oauth2.Endpoint { func (p *Provider) Endpoint() oauth2.Endpoint {
return oauth2.Endpoint{AuthURL: p.authURL, TokenURL: p.tokenURL} return oauth2.Endpoint{AuthURL: p.authURL, DeviceAuthURL: p.deviceAuthURL, TokenURL: p.tokenURL}
} }
// UserInfoEndpoint returns the OpenID Connect userinfo endpoint for the given // UserInfoEndpoint returns the OpenID Connect userinfo endpoint for the given
@ -332,7 +339,7 @@ func (p *Provider) UserInfo(ctx context.Context, tokenSource oauth2.TokenSource)
return nil, err return nil, err
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) body, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -7,12 +7,12 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io/ioutil" "io"
"net/http" "net/http"
"strings" "strings"
"time" "time"
jose "github.com/go-jose/go-jose/v3" jose "github.com/go-jose/go-jose/v4"
"golang.org/x/oauth2" "golang.org/x/oauth2"
) )
@ -182,7 +182,7 @@ func resolveDistributedClaim(ctx context.Context, verifier *IDTokenVerifier, src
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) body, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to read response body: %v", err) return nil, fmt.Errorf("unable to read response body: %v", err)
} }
@ -310,7 +310,16 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
return t, nil return t, nil
} }
jws, err := jose.ParseSigned(rawIDToken) var supportedSigAlgs []jose.SignatureAlgorithm
for _, alg := range v.config.SupportedSigningAlgs {
supportedSigAlgs = append(supportedSigAlgs, jose.SignatureAlgorithm(alg))
}
if len(supportedSigAlgs) == 0 {
// If no algorithms were specified by both the config and discovery, default
// to the one mandatory algorithm "RS256".
supportedSigAlgs = []jose.SignatureAlgorithm{jose.RS256}
}
jws, err := jose.ParseSigned(rawIDToken, supportedSigAlgs)
if err != nil { if err != nil {
return nil, fmt.Errorf("oidc: malformed jwt: %v", err) return nil, fmt.Errorf("oidc: malformed jwt: %v", err)
} }
@ -322,17 +331,7 @@ func (v *IDTokenVerifier) Verify(ctx context.Context, rawIDToken string) (*IDTok
default: default:
return nil, fmt.Errorf("oidc: multiple signatures on id token not supported") return nil, fmt.Errorf("oidc: multiple signatures on id token not supported")
} }
sig := jws.Signatures[0] sig := jws.Signatures[0]
supportedSigAlgs := v.config.SupportedSigningAlgs
if len(supportedSigAlgs) == 0 {
supportedSigAlgs = []string{RS256}
}
if !contains(supportedSigAlgs, sig.Header.Algorithm) {
return nil, fmt.Errorf("oidc: id token signed with unsupported algorithm, expected %q got %q", supportedSigAlgs, sig.Header.Algorithm)
}
t.sigAlgorithm = sig.Header.Algorithm t.sigAlgorithm = sig.Header.Algorithm
ctx = context.WithValue(ctx, parsedJWTKey, jws) ctx = context.WithValue(ctx, parsedJWTKey, jws)

View File

@ -1,10 +0,0 @@
Serious about security
======================
Square recognizes the important contributions the security research community
can make. We therefore encourage reporting security issues with the code
contained in this repository.
If you believe you have discovered a security vulnerability, please follow the
guidelines at <https://bugcrowd.com/squareopensource>.

View File

@ -1,133 +0,0 @@
/*-
* Copyright 2016 Zbigniew Mandziejewicz
* Copyright 2016 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jwt
import (
"fmt"
"strings"
jose "github.com/go-jose/go-jose/v3"
"github.com/go-jose/go-jose/v3/json"
)
// JSONWebToken represents a JSON Web Token (as specified in RFC7519).
type JSONWebToken struct {
payload func(k interface{}) ([]byte, error)
unverifiedPayload func() []byte
Headers []jose.Header
}
type NestedJSONWebToken struct {
enc *jose.JSONWebEncryption
Headers []jose.Header
}
// Claims deserializes a JSONWebToken into dest using the provided key.
func (t *JSONWebToken) Claims(key interface{}, dest ...interface{}) error {
b, err := t.payload(key)
if err != nil {
return err
}
for _, d := range dest {
if err := json.Unmarshal(b, d); err != nil {
return err
}
}
return nil
}
// UnsafeClaimsWithoutVerification deserializes the claims of a
// JSONWebToken into the dests. For signed JWTs, the claims are not
// verified. This function won't work for encrypted JWTs.
func (t *JSONWebToken) UnsafeClaimsWithoutVerification(dest ...interface{}) error {
if t.unverifiedPayload == nil {
return fmt.Errorf("go-jose/go-jose: Cannot get unverified claims")
}
claims := t.unverifiedPayload()
for _, d := range dest {
if err := json.Unmarshal(claims, d); err != nil {
return err
}
}
return nil
}
func (t *NestedJSONWebToken) Decrypt(decryptionKey interface{}) (*JSONWebToken, error) {
b, err := t.enc.Decrypt(decryptionKey)
if err != nil {
return nil, err
}
sig, err := ParseSigned(string(b))
if err != nil {
return nil, err
}
return sig, nil
}
// ParseSigned parses token from JWS form.
func ParseSigned(s string) (*JSONWebToken, error) {
sig, err := jose.ParseSigned(s)
if err != nil {
return nil, err
}
headers := make([]jose.Header, len(sig.Signatures))
for i, signature := range sig.Signatures {
headers[i] = signature.Header
}
return &JSONWebToken{
payload: sig.Verify,
unverifiedPayload: sig.UnsafePayloadWithoutVerification,
Headers: headers,
}, nil
}
// ParseEncrypted parses token from JWE form.
func ParseEncrypted(s string) (*JSONWebToken, error) {
enc, err := jose.ParseEncrypted(s)
if err != nil {
return nil, err
}
return &JSONWebToken{
payload: enc.Decrypt,
Headers: []jose.Header{enc.Header},
}, nil
}
// ParseSignedAndEncrypted parses signed-then-encrypted token from JWE form.
func ParseSignedAndEncrypted(s string) (*NestedJSONWebToken, error) {
enc, err := jose.ParseEncrypted(s)
if err != nil {
return nil, err
}
contentType, _ := enc.Header.ExtraHeaders[jose.HeaderContentType].(string)
if strings.ToUpper(contentType) != "JWT" {
return nil, ErrInvalidContentType
}
return &NestedJSONWebToken{
enc: enc,
Headers: []jose.Header{enc.Header},
}, nil
}

72
vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,72 @@
# v4.0.1
## Fixed
- An attacker could send a JWE containing compressed data that used large
amounts of memory and CPU when decompressed by `Decrypt` or `DecryptMulti`.
Those functions now return an error if the decompressed data would exceed
250kB or 10x the compressed size (whichever is larger). Thanks to
Enze Wang@Alioth and Jianjun Chen@Zhongguancun Lab (@zer0yu and @chenjj)
for reporting.
# v4.0.0
This release makes some breaking changes in order to more thoroughly
address the vulnerabilities discussed in [Three New Attacks Against JSON Web
Tokens][1], "Sign/encrypt confusion", "Billion hash attack", and "Polyglot
token".
## Changed
- Limit JWT encryption types (exclude password or public key types) (#78)
- Enforce minimum length for HMAC keys (#85)
- jwt: match any audience in a list, rather than requiring all audiences (#81)
- jwt: accept only Compact Serialization (#75)
- jws: Add expected algorithms for signatures (#74)
- Require specifying expected algorithms for ParseEncrypted,
ParseSigned, ParseDetached, jwt.ParseEncrypted, jwt.ParseSigned,
jwt.ParseSignedAndEncrypted (#69, #74)
- Usually there is a small, known set of appropriate algorithms for a program
to use and it's a mistake to allow unexpected algorithms. For instance the
"billion hash attack" relies in part on programs accepting the PBES2
encryption algorithm and doing the necessary work even if they weren't
specifically configured to allow PBES2.
- Revert "Strip padding off base64 strings" (#82)
- The specs require base64url encoding without padding.
- Minimum supported Go version is now 1.21
## Added
- ParseSignedCompact, ParseSignedJSON, ParseEncryptedCompact, ParseEncryptedJSON.
- These allow parsing a specific serialization, as opposed to ParseSigned and
ParseEncrypted, which try to automatically detect which serialization was
provided. It's common to require a specific serialization for a specific
protocol - for instance JWT requires Compact serialization.
[1]: https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf
# v3.0.2
## Fixed
- DecryptMulti: handle decompression error (#19)
## Changed
- jwe/CompactSerialize: improve performance (#67)
- Increase the default number of PBKDF2 iterations to 600k (#48)
- Return the proper algorithm for ECDSA keys (#45)
## Added
- Add Thumbprint support for opaque signers (#38)
# v3.0.1
## Fixed
- Security issue: an attacker specifying a large "p2c" value can cause
JSONWebEncryption.Decrypt and JSONWebEncryption.DecryptMulti to consume large
amounts of CPU, causing a DoS. Thanks to Matt Schwager (@mschwager) for the
disclosure and to Tom Tervoort for originally publishing the category of attack.
https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf

View File

@ -1,10 +1,9 @@
# Go JOSE # Go JOSE
[![godoc](http://img.shields.io/badge/godoc-jose_package-blue.svg?style=flat)](https://godoc.org/gopkg.in/go-jose/go-jose.v2) [![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4)
[![godoc](http://img.shields.io/badge/godoc-jwt_package-blue.svg?style=flat)](https://godoc.org/gopkg.in/go-jose/go-jose.v2/jwt) [![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4/jwt.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt)
[![license](http://img.shields.io/badge/license-apache_2.0-blue.svg?style=flat)](https://raw.githubusercontent.com/go-jose/go-jose/master/LICENSE) [![license](https://img.shields.io/badge/license-apache_2.0-blue.svg?style=flat)](https://raw.githubusercontent.com/go-jose/go-jose/master/LICENSE)
[![build](https://travis-ci.org/go-jose/go-jose.svg?branch=master)](https://travis-ci.org/go-jose/go-jose) [![test](https://img.shields.io/github/checks-status/go-jose/go-jose/v4)](https://github.com/go-jose/go-jose/actions)
[![coverage](https://coveralls.io/repos/github/go-jose/go-jose/badge.svg?branch=master)](https://coveralls.io/r/go-jose/go-jose)
Package jose aims to provide an implementation of the Javascript Object Signing Package jose aims to provide an implementation of the Javascript Object Signing
and Encryption set of standards. This includes support for JSON Web Encryption, and Encryption set of standards. This includes support for JSON Web Encryption,
@ -21,13 +20,13 @@ US maintained blocked list.
## Overview ## Overview
The implementation follows the The implementation follows the
[JSON Web Encryption](http://dx.doi.org/10.17487/RFC7516) (RFC 7516), [JSON Web Encryption](https://dx.doi.org/10.17487/RFC7516) (RFC 7516),
[JSON Web Signature](http://dx.doi.org/10.17487/RFC7515) (RFC 7515), and [JSON Web Signature](https://dx.doi.org/10.17487/RFC7515) (RFC 7515), and
[JSON Web Token](http://dx.doi.org/10.17487/RFC7519) (RFC 7519) specifications. [JSON Web Token](https://dx.doi.org/10.17487/RFC7519) (RFC 7519) specifications.
Tables of supported algorithms are shown below. The library supports both Tables of supported algorithms are shown below. The library supports both
the compact and JWS/JWE JSON Serialization formats, and has optional support for the compact and JWS/JWE JSON Serialization formats, and has optional support for
multiple recipients. It also comes with a small command-line utility multiple recipients. It also comes with a small command-line utility
([`jose-util`](https://github.com/go-jose/go-jose/tree/master/jose-util)) ([`jose-util`](https://pkg.go.dev/github.com/go-jose/go-jose/jose-util))
for dealing with JOSE messages in a shell. for dealing with JOSE messages in a shell.
**Note**: We use a forked version of the `encoding/json` package from the Go **Note**: We use a forked version of the `encoding/json` package from the Go
@ -38,29 +37,22 @@ libraries in other languages.
### Versions ### Versions
[Version 2](https://gopkg.in/go-jose/go-jose.v2) [Version 4](https://github.com/go-jose/go-jose)
([branch](https://github.com/go-jose/go-jose/tree/v2), ([branch](https://github.com/go-jose/go-jose/tree/main),
[doc](https://godoc.org/gopkg.in/go-jose/go-jose.v2)) is the current stable version: [doc](https://pkg.go.dev/github.com/go-jose/go-jose/v4), [releases](https://github.com/go-jose/go-jose/releases)) is the current stable version:
import "gopkg.in/go-jose/go-jose.v2" import "github.com/go-jose/go-jose/v4"
[Version 3](https://github.com/go-jose/go-jose) The old [square/go-jose](https://github.com/square/go-jose) repo contains the prior v1 and v2 versions, which
([branch](https://github.com/go-jose/go-jose/tree/master), are still useable but not actively developed anymore.
[doc](https://godoc.org/github.com/go-jose/go-jose)) is the under development/unstable version (not released yet):
import "github.com/go-jose/go-jose/v3" Version 3, in this repo, is still receiving security fixes but not functionality
updates.
All new feature development takes place on the `master` branch, which we are
preparing to release as version 3 soon. Version 2 will continue to receive
critical bug and security fixes. Note that starting with version 3 we are
using Go modules for versioning instead of `gopkg.in` as before. Version 3 also will require Go version 1.13 or higher.
Version 1 (on the `v1` branch) is frozen and not supported anymore.
### Supported algorithms ### Supported algorithms
See below for a table of supported algorithms. Algorithm identifiers match See below for a table of supported algorithms. Algorithm identifiers match
the names in the [JSON Web Algorithms](http://dx.doi.org/10.17487/RFC7518) the names in the [JSON Web Algorithms](https://dx.doi.org/10.17487/RFC7518)
standard where possible. The Godoc reference has a list of constants. standard where possible. The Godoc reference has a list of constants.
Key encryption | Algorithm identifier(s) Key encryption | Algorithm identifier(s)
@ -103,20 +95,20 @@ allows attaching a key id.
Algorithm(s) | Corresponding types Algorithm(s) | Corresponding types
:------------------------- | ------------------------------- :------------------------- | -------------------------------
RSA | *[rsa.PublicKey](http://golang.org/pkg/crypto/rsa/#PublicKey), *[rsa.PrivateKey](http://golang.org/pkg/crypto/rsa/#PrivateKey) RSA | *[rsa.PublicKey](https://pkg.go.dev/crypto/rsa/#PublicKey), *[rsa.PrivateKey](https://pkg.go.dev/crypto/rsa/#PrivateKey)
ECDH, ECDSA | *[ecdsa.PublicKey](http://golang.org/pkg/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](http://golang.org/pkg/crypto/ecdsa/#PrivateKey) ECDH, ECDSA | *[ecdsa.PublicKey](https://pkg.go.dev/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](https://pkg.go.dev/crypto/ecdsa/#PrivateKey)
EdDSA<sup>1</sup> | [ed25519.PublicKey](https://godoc.org/pkg/crypto/ed25519#PublicKey), [ed25519.PrivateKey](https://godoc.org/pkg/crypto/ed25519#PrivateKey) EdDSA<sup>1</sup> | [ed25519.PublicKey](https://pkg.go.dev/crypto/ed25519#PublicKey), [ed25519.PrivateKey](https://pkg.go.dev/crypto/ed25519#PrivateKey)
AES, HMAC | []byte AES, HMAC | []byte
<sup>1. Only available in version 2 or later of the package</sup> <sup>1. Only available in version 2 or later of the package</sup>
## Examples ## Examples
[![godoc](http://img.shields.io/badge/godoc-jose_package-blue.svg?style=flat)](https://godoc.org/gopkg.in/go-jose/go-jose.v2) [![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4)
[![godoc](http://img.shields.io/badge/godoc-jwt_package-blue.svg?style=flat)](https://godoc.org/gopkg.in/go-jose/go-jose.v2/jwt) [![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4/jwt.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt)
Examples can be found in the Godoc Examples can be found in the Godoc
reference for this package. The reference for this package. The
[`jose-util`](https://github.com/go-jose/go-jose/tree/master/jose-util) [`jose-util`](https://github.com/go-jose/go-jose/tree/v4/jose-util)
subdirectory also contains a small command-line utility which might be useful subdirectory also contains a small command-line utility which might be useful
as an example as well. as an example as well.

13
vendor/github.com/go-jose/go-jose/v4/SECURITY.md generated vendored Normal file
View File

@ -0,0 +1,13 @@
# Security Policy
This document explains how to contact the Let's Encrypt security team to report security vulnerabilities.
## Supported Versions
| Version | Supported |
| ------- | ----------|
| >= v3 | &check; |
| v2 | &cross; |
| v1 | &cross; |
## Reporting a vulnerability
Please see [https://letsencrypt.org/contact/#security](https://letsencrypt.org/contact/#security) for the email address to report a vulnerability. Ensure that the subject line for your report contains the word `vulnerability` and is descriptive. Your email should be acknowledged within 24 hours. If you do not receive a response within 24 hours, please follow-up again with another email.

View File

@ -29,8 +29,8 @@ import (
"fmt" "fmt"
"math/big" "math/big"
josecipher "github.com/go-jose/go-jose/v3/cipher" josecipher "github.com/go-jose/go-jose/v4/cipher"
"github.com/go-jose/go-jose/v3/json" "github.com/go-jose/go-jose/v4/json"
) )
// A generic RSA-based encrypter/verifier // A generic RSA-based encrypter/verifier
@ -285,6 +285,9 @@ func (ctx rsaDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm
switch alg { switch alg {
case RS256, RS384, RS512: case RS256, RS384, RS512:
// TODO(https://github.com/go-jose/go-jose/issues/40): As of go1.20, the
// random parameter is legacy and ignored, and it can be nil.
// https://cs.opensource.google/go/go/+/refs/tags/go1.20:src/crypto/rsa/pkcs1v15.go;l=263;bpv=0;bpt=1
out, err = rsa.SignPKCS1v15(RandReader, ctx.privateKey, hash, hashed) out, err = rsa.SignPKCS1v15(RandReader, ctx.privateKey, hash, hashed)
case PS256, PS384, PS512: case PS256, PS384, PS512:
out, err = rsa.SignPSS(RandReader, ctx.privateKey, hash, hashed, &rsa.PSSOptions{ out, err = rsa.SignPSS(RandReader, ctx.privateKey, hash, hashed, &rsa.PSSOptions{

View File

@ -21,9 +21,8 @@ import (
"crypto/rsa" "crypto/rsa"
"errors" "errors"
"fmt" "fmt"
"reflect"
"github.com/go-jose/go-jose/v3/json" "github.com/go-jose/go-jose/v4/json"
) )
// Encrypter represents an encrypter which produces an encrypted JWE object. // Encrypter represents an encrypter which produces an encrypted JWE object.
@ -76,14 +75,24 @@ type recipientKeyInfo struct {
type EncrypterOptions struct { type EncrypterOptions struct {
Compression CompressionAlgorithm Compression CompressionAlgorithm
// Optional map of additional keys to be inserted into the protected header // Optional map of name/value pairs to be inserted into the protected
// of a JWS object. Some specifications which make use of JWS like to insert // header of a JWS object. Some specifications which make use of
// additional values here. All values must be JSON-serializable. // JWS require additional values here.
//
// Values will be serialized by [json.Marshal] and must be valid inputs to
// that function.
//
// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal
ExtraHeaders map[HeaderKey]interface{} ExtraHeaders map[HeaderKey]interface{}
} }
// WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it // WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it
// if necessary. It returns itself and so can be used in a fluent style. // if necessary, and returns the updated EncrypterOptions.
//
// The v parameter will be serialized by [json.Marshal] and must be a valid
// input to that function.
//
// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal
func (eo *EncrypterOptions) WithHeader(k HeaderKey, v interface{}) *EncrypterOptions { func (eo *EncrypterOptions) WithHeader(k HeaderKey, v interface{}) *EncrypterOptions {
if eo.ExtraHeaders == nil { if eo.ExtraHeaders == nil {
eo.ExtraHeaders = map[HeaderKey]interface{}{} eo.ExtraHeaders = map[HeaderKey]interface{}{}
@ -112,6 +121,16 @@ func (eo *EncrypterOptions) WithType(typ ContentType) *EncrypterOptions {
// be generated. // be generated.
type Recipient struct { type Recipient struct {
Algorithm KeyAlgorithm Algorithm KeyAlgorithm
// Key must have one of these types:
// - ed25519.PublicKey
// - *ecdsa.PublicKey
// - *rsa.PublicKey
// - *JSONWebKey
// - JSONWebKey
// - []byte (a symmetric key)
// - Any type that satisfies the OpaqueKeyEncrypter interface
//
// The type of Key must match the value of Algorithm.
Key interface{} Key interface{}
KeyID string KeyID string
PBES2Count int PBES2Count int
@ -150,16 +169,17 @@ func NewEncrypter(enc ContentEncryption, rcpt Recipient, opts *EncrypterOptions)
switch rcpt.Algorithm { switch rcpt.Algorithm {
case DIRECT: case DIRECT:
// Direct encryption mode must be treated differently // Direct encryption mode must be treated differently
if reflect.TypeOf(rawKey) != reflect.TypeOf([]byte{}) { keyBytes, ok := rawKey.([]byte)
if !ok {
return nil, ErrUnsupportedKeyType return nil, ErrUnsupportedKeyType
} }
if encrypter.cipher.keySize() != len(rawKey.([]byte)) { if encrypter.cipher.keySize() != len(keyBytes) {
return nil, ErrInvalidKeySize return nil, ErrInvalidKeySize
} }
encrypter.keyGenerator = staticKeyGenerator{ encrypter.keyGenerator = staticKeyGenerator{
key: rawKey.([]byte), key: keyBytes,
} }
recipientInfo, _ := newSymmetricRecipient(rcpt.Algorithm, rawKey.([]byte)) recipientInfo, _ := newSymmetricRecipient(rcpt.Algorithm, keyBytes)
recipientInfo.keyID = keyID recipientInfo.keyID = keyID
if rcpt.KeyID != "" { if rcpt.KeyID != "" {
recipientInfo.keyID = rcpt.KeyID recipientInfo.keyID = rcpt.KeyID
@ -168,16 +188,16 @@ func NewEncrypter(enc ContentEncryption, rcpt Recipient, opts *EncrypterOptions)
return encrypter, nil return encrypter, nil
case ECDH_ES: case ECDH_ES:
// ECDH-ES (w/o key wrapping) is similar to DIRECT mode // ECDH-ES (w/o key wrapping) is similar to DIRECT mode
typeOf := reflect.TypeOf(rawKey) keyDSA, ok := rawKey.(*ecdsa.PublicKey)
if typeOf != reflect.TypeOf(&ecdsa.PublicKey{}) { if !ok {
return nil, ErrUnsupportedKeyType return nil, ErrUnsupportedKeyType
} }
encrypter.keyGenerator = ecKeyGenerator{ encrypter.keyGenerator = ecKeyGenerator{
size: encrypter.cipher.keySize(), size: encrypter.cipher.keySize(),
algID: string(enc), algID: string(enc),
publicKey: rawKey.(*ecdsa.PublicKey), publicKey: keyDSA,
} }
recipientInfo, _ := newECDHRecipient(rcpt.Algorithm, rawKey.(*ecdsa.PublicKey)) recipientInfo, _ := newECDHRecipient(rcpt.Algorithm, keyDSA)
recipientInfo.keyID = keyID recipientInfo.keyID = keyID
if rcpt.KeyID != "" { if rcpt.KeyID != "" {
recipientInfo.keyID = rcpt.KeyID recipientInfo.keyID = rcpt.KeyID
@ -270,9 +290,8 @@ func makeJWERecipient(alg KeyAlgorithm, encryptionKey interface{}) (recipientKey
recipient, err := makeJWERecipient(alg, encryptionKey.Key) recipient, err := makeJWERecipient(alg, encryptionKey.Key)
recipient.keyID = encryptionKey.KeyID recipient.keyID = encryptionKey.KeyID
return recipient, err return recipient, err
} case OpaqueKeyEncrypter:
if encrypter, ok := encryptionKey.(OpaqueKeyEncrypter); ok { return newOpaqueKeyEncrypter(alg, encryptionKey)
return newOpaqueKeyEncrypter(alg, encrypter)
} }
return recipientKeyInfo{}, ErrUnsupportedKeyType return recipientKeyInfo{}, ErrUnsupportedKeyType
} }
@ -300,11 +319,11 @@ func newDecrypter(decryptionKey interface{}) (keyDecrypter, error) {
return newDecrypter(decryptionKey.Key) return newDecrypter(decryptionKey.Key)
case *JSONWebKey: case *JSONWebKey:
return newDecrypter(decryptionKey.Key) return newDecrypter(decryptionKey.Key)
} case OpaqueKeyDecrypter:
if okd, ok := decryptionKey.(OpaqueKeyDecrypter); ok { return &opaqueKeyDecrypter{decrypter: decryptionKey}, nil
return &opaqueKeyDecrypter{decrypter: okd}, nil default:
}
return nil, ErrUnsupportedKeyType return nil, ErrUnsupportedKeyType
}
} }
// Implementation of encrypt method producing a JWE object. // Implementation of encrypt method producing a JWE object.
@ -403,9 +422,27 @@ func (ctx *genericEncrypter) Options() EncrypterOptions {
} }
} }
// Decrypt and validate the object and return the plaintext. Note that this // Decrypt and validate the object and return the plaintext. This
// function does not support multi-recipient, if you desire multi-recipient // function does not support multi-recipient. If you desire multi-recipient
// decryption use DecryptMulti instead. // decryption use DecryptMulti instead.
//
// The decryptionKey argument must contain a private or symmetric key
// and must have one of these types:
// - *ecdsa.PrivateKey
// - *rsa.PrivateKey
// - *JSONWebKey
// - JSONWebKey
// - *JSONWebKeySet
// - JSONWebKeySet
// - []byte (a symmetric key)
// - string (a symmetric key)
// - Any type that satisfies the OpaqueKeyDecrypter interface.
//
// Note that ed25519 is only available for signatures, not encryption, so is
// not an option here.
//
// Automatically decompresses plaintext, but returns an error if the decompressed
// data would be >250kB or >10x the size of the compressed data, whichever is larger.
func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) { func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) {
headers := obj.mergedHeaders(nil) headers := obj.mergedHeaders(nil)
@ -462,15 +499,24 @@ func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error)
// The "zip" header parameter may only be present in the protected header. // The "zip" header parameter may only be present in the protected header.
if comp := obj.protected.getCompression(); comp != "" { if comp := obj.protected.getCompression(); comp != "" {
plaintext, err = decompress(comp, plaintext) plaintext, err = decompress(comp, plaintext)
if err != nil {
return nil, fmt.Errorf("go-jose/go-jose: failed to decompress plaintext: %v", err)
}
} }
return plaintext, err return plaintext, nil
} }
// DecryptMulti decrypts and validates the object and returns the plaintexts, // DecryptMulti decrypts and validates the object and returns the plaintexts,
// with support for multiple recipients. It returns the index of the recipient // with support for multiple recipients. It returns the index of the recipient
// for which the decryption was successful, the merged headers for that recipient, // for which the decryption was successful, the merged headers for that recipient,
// and the plaintext. // and the plaintext.
//
// The decryptionKey argument must have one of the types allowed for the
// decryptionKey argument of Decrypt().
//
// Automatically decompresses plaintext, but returns an error if the decompressed
// data would be >250kB or >3x the size of the compressed data, whichever is larger.
func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Header, []byte, error) { func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Header, []byte, error) {
globalHeaders := obj.mergedHeaders(nil) globalHeaders := obj.mergedHeaders(nil)
@ -532,7 +578,10 @@ func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Heade
// The "zip" header parameter may only be present in the protected header. // The "zip" header parameter may only be present in the protected header.
if comp := obj.protected.getCompression(); comp != "" { if comp := obj.protected.getCompression(); comp != "" {
plaintext, _ = decompress(comp, plaintext) plaintext, err = decompress(comp, plaintext)
if err != nil {
return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: failed to decompress plaintext: %v", err)
}
} }
sanitized, err := headers.sanitized() sanitized, err := headers.sanitized()

View File

@ -15,13 +15,11 @@
*/ */
/* /*
Package jose aims to provide an implementation of the Javascript Object Signing Package jose aims to provide an implementation of the Javascript Object Signing
and Encryption set of standards. It implements encryption and signing based on and Encryption set of standards. It implements encryption and signing based on
the JSON Web Encryption and JSON Web Signature standards, with optional JSON Web the JSON Web Encryption and JSON Web Signature standards, with optional JSON Web
Token support available in a sub-package. The library supports both the compact Token support available in a sub-package. The library supports both the compact
and JWS/JWE JSON Serialization formats, and has optional support for multiple and JWS/JWE JSON Serialization formats, and has optional support for multiple
recipients. recipients.
*/ */
package jose package jose

View File

@ -21,12 +21,13 @@ import (
"compress/flate" "compress/flate"
"encoding/base64" "encoding/base64"
"encoding/binary" "encoding/binary"
"fmt"
"io" "io"
"math/big" "math/big"
"strings" "strings"
"unicode" "unicode"
"github.com/go-jose/go-jose/v3/json" "github.com/go-jose/go-jose/v4/json"
) )
// Helper function to serialize known-good objects. // Helper function to serialize known-good objects.
@ -85,7 +86,7 @@ func decompress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) {
} }
} }
// Compress with DEFLATE // deflate compresses the input.
func deflate(input []byte) ([]byte, error) { func deflate(input []byte) ([]byte, error) {
output := new(bytes.Buffer) output := new(bytes.Buffer)
@ -97,15 +98,24 @@ func deflate(input []byte) ([]byte, error) {
return output.Bytes(), err return output.Bytes(), err
} }
// Decompress with DEFLATE // inflate decompresses the input.
//
// Errors if the decompressed data would be >250kB or >10x the size of the
// compressed data, whichever is larger.
func inflate(input []byte) ([]byte, error) { func inflate(input []byte) ([]byte, error) {
output := new(bytes.Buffer) output := new(bytes.Buffer)
reader := flate.NewReader(bytes.NewBuffer(input)) reader := flate.NewReader(bytes.NewBuffer(input))
_, err := io.Copy(output, reader) maxCompressedSize := max(250_000, 10*int64(len(input)))
if err != nil {
limit := maxCompressedSize + 1
n, err := io.CopyN(output, reader, limit)
if err != nil && err != io.EOF {
return nil, err return nil, err
} }
if n == limit {
return nil, fmt.Errorf("uncompressed data would be too large (>%d bytes)", maxCompressedSize)
}
err = reader.Close() err = reader.Close()
return output.Bytes(), err return output.Bytes(), err
@ -154,7 +164,7 @@ func (b *byteBuffer) UnmarshalJSON(data []byte) error {
return nil return nil
} }
decoded, err := base64URLDecode(encoded) decoded, err := base64.RawURLEncoding.DecodeString(encoded)
if err != nil { if err != nil {
return err return err
} }
@ -184,8 +194,35 @@ func (b byteBuffer) toInt() int {
return int(b.bigInt().Int64()) return int(b.bigInt().Int64())
} }
// base64URLDecode is implemented as defined in https://www.rfc-editor.org/rfc/rfc7515.html#appendix-C func base64EncodeLen(sl []byte) int {
func base64URLDecode(value string) ([]byte, error) { return base64.RawURLEncoding.EncodedLen(len(sl))
value = strings.TrimRight(value, "=") }
return base64.RawURLEncoding.DecodeString(value)
func base64JoinWithDots(inputs ...[]byte) string {
if len(inputs) == 0 {
return ""
}
// Count of dots.
totalCount := len(inputs) - 1
for _, input := range inputs {
totalCount += base64EncodeLen(input)
}
out := make([]byte, totalCount)
startEncode := 0
for i, input := range inputs {
base64.RawURLEncoding.Encode(out[startEncode:], input)
if i == len(inputs)-1 {
continue
}
startEncode += base64EncodeLen(input)
out[startEncode] = '.'
startEncode++
}
return string(out)
} }

View File

@ -75,14 +75,13 @@ import (
// //
// The JSON null value unmarshals into an interface, map, pointer, or slice // The JSON null value unmarshals into an interface, map, pointer, or slice
// by setting that Go value to nil. Because null is often used in JSON to mean // by setting that Go value to nil. Because null is often used in JSON to mean
// ``not present,'' unmarshaling a JSON null into any other Go type has no effect // “not present,” unmarshaling a JSON null into any other Go type has no effect
// on the value and produces no error. // on the value and produces no error.
// //
// When unmarshaling quoted strings, invalid UTF-8 or // When unmarshaling quoted strings, invalid UTF-8 or
// invalid UTF-16 surrogate pairs are not treated as an error. // invalid UTF-16 surrogate pairs are not treated as an error.
// Instead, they are replaced by the Unicode replacement // Instead, they are replaced by the Unicode replacement
// character U+FFFD. // character U+FFFD.
//
func Unmarshal(data []byte, v interface{}) error { func Unmarshal(data []byte, v interface{}) error {
// Check for well-formedness. // Check for well-formedness.
// Avoids filling out half a data structure // Avoids filling out half a data structure

View File

@ -58,6 +58,7 @@ import (
// becomes a member of the object unless // becomes a member of the object unless
// - the field's tag is "-", or // - the field's tag is "-", or
// - the field is empty and its tag specifies the "omitempty" option. // - the field is empty and its tag specifies the "omitempty" option.
//
// The empty values are false, 0, any // The empty values are false, 0, any
// nil pointer or interface value, and any array, slice, map, or string of // nil pointer or interface value, and any array, slice, map, or string of
// length zero. The object's default key string is the struct field name // length zero. The object's default key string is the struct field name
@ -133,7 +134,6 @@ import (
// JSON cannot represent cyclic data structures and Marshal does not // JSON cannot represent cyclic data structures and Marshal does not
// handle them. Passing cyclic structures to Marshal will result in // handle them. Passing cyclic structures to Marshal will result in
// an infinite recursion. // an infinite recursion.
//
func Marshal(v interface{}) ([]byte, error) { func Marshal(v interface{}) ([]byte, error) {
e := &encodeState{} e := &encodeState{}
err := e.marshal(v) err := e.marshal(v)

View File

@ -240,7 +240,6 @@ var _ Unmarshaler = (*RawMessage)(nil)
// Number, for JSON numbers // Number, for JSON numbers
// string, for JSON string literals // string, for JSON string literals
// nil, for JSON null // nil, for JSON null
//
type Token interface{} type Token interface{}
const ( const (

View File

@ -18,10 +18,11 @@ package jose
import ( import (
"encoding/base64" "encoding/base64"
"errors"
"fmt" "fmt"
"strings" "strings"
"github.com/go-jose/go-jose/v3/json" "github.com/go-jose/go-jose/v4/json"
) )
// rawJSONWebEncryption represents a raw JWE JSON object. Used for parsing/serializing. // rawJSONWebEncryption represents a raw JWE JSON object. Used for parsing/serializing.
@ -104,29 +105,75 @@ func (obj JSONWebEncryption) computeAuthData() []byte {
return output return output
} }
// ParseEncrypted parses an encrypted message in compact or JWE JSON Serialization format. func containsKeyAlgorithm(haystack []KeyAlgorithm, needle KeyAlgorithm) bool {
func ParseEncrypted(input string) (*JSONWebEncryption, error) { for _, algorithm := range haystack {
input = stripWhitespace(input) if algorithm == needle {
if strings.HasPrefix(input, "{") { return true
return parseEncryptedFull(input)
} }
}
return parseEncryptedCompact(input) return false
} }
// parseEncryptedFull parses a message in compact format. func containsContentEncryption(haystack []ContentEncryption, needle ContentEncryption) bool {
func parseEncryptedFull(input string) (*JSONWebEncryption, error) { for _, algorithm := range haystack {
if algorithm == needle {
return true
}
}
return false
}
// ParseEncrypted parses an encrypted message in JWE Compact or JWE JSON Serialization.
//
// https://datatracker.ietf.org/doc/html/rfc7516#section-3.1
// https://datatracker.ietf.org/doc/html/rfc7516#section-3.2
//
// The keyAlgorithms and contentEncryption parameters are used to validate the "alg" and "enc"
// header parameters respectively. They must be nonempty, and each "alg" or "enc" header in
// parsed data must contain a value that is present in the corresponding parameter. That
// includes the protected and unprotected headers as well as all recipients. To accept
// multiple algorithms, pass a slice of all the algorithms you want to accept.
func ParseEncrypted(input string,
keyEncryptionAlgorithms []KeyAlgorithm,
contentEncryption []ContentEncryption,
) (*JSONWebEncryption, error) {
input = stripWhitespace(input)
if strings.HasPrefix(input, "{") {
return ParseEncryptedJSON(input, keyEncryptionAlgorithms, contentEncryption)
}
return ParseEncryptedCompact(input, keyEncryptionAlgorithms, contentEncryption)
}
// ParseEncryptedJSON parses a message in JWE JSON Serialization.
//
// https://datatracker.ietf.org/doc/html/rfc7516#section-3.2
func ParseEncryptedJSON(
input string,
keyEncryptionAlgorithms []KeyAlgorithm,
contentEncryption []ContentEncryption,
) (*JSONWebEncryption, error) {
var parsed rawJSONWebEncryption var parsed rawJSONWebEncryption
err := json.Unmarshal([]byte(input), &parsed) err := json.Unmarshal([]byte(input), &parsed)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return parsed.sanitized() return parsed.sanitized(keyEncryptionAlgorithms, contentEncryption)
} }
// sanitized produces a cleaned-up JWE object from the raw JSON. // sanitized produces a cleaned-up JWE object from the raw JSON.
func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) { func (parsed *rawJSONWebEncryption) sanitized(
keyEncryptionAlgorithms []KeyAlgorithm,
contentEncryption []ContentEncryption,
) (*JSONWebEncryption, error) {
if len(keyEncryptionAlgorithms) == 0 {
return nil, errors.New("go-jose/go-jose: no key algorithms provided")
}
if len(contentEncryption) == 0 {
return nil, errors.New("go-jose/go-jose: no content encryption algorithms provided")
}
obj := &JSONWebEncryption{ obj := &JSONWebEncryption{
original: parsed, original: parsed,
unprotected: parsed.Unprotected, unprotected: parsed.Unprotected,
@ -170,7 +217,7 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) {
} else { } else {
obj.recipients = make([]recipientInfo, len(parsed.Recipients)) obj.recipients = make([]recipientInfo, len(parsed.Recipients))
for r := range parsed.Recipients { for r := range parsed.Recipients {
encryptedKey, err := base64URLDecode(parsed.Recipients[r].EncryptedKey) encryptedKey, err := base64.RawURLEncoding.DecodeString(parsed.Recipients[r].EncryptedKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -185,10 +232,31 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) {
} }
} }
for _, recipient := range obj.recipients { for i, recipient := range obj.recipients {
headers := obj.mergedHeaders(&recipient) headers := obj.mergedHeaders(&recipient)
if headers.getAlgorithm() == "" || headers.getEncryption() == "" { if headers.getAlgorithm() == "" {
return nil, fmt.Errorf("go-jose/go-jose: message is missing alg/enc headers") return nil, fmt.Errorf(`go-jose/go-jose: recipient %d: missing header "alg"`, i)
}
if headers.getEncryption() == "" {
return nil, fmt.Errorf(`go-jose/go-jose: recipient %d: missing header "enc"`, i)
}
err := validateAlgEnc(headers, keyEncryptionAlgorithms, contentEncryption)
if err != nil {
return nil, fmt.Errorf("go-jose/go-jose: recipient %d: %s", i, err)
}
}
if obj.protected != nil {
err := validateAlgEnc(*obj.protected, keyEncryptionAlgorithms, contentEncryption)
if err != nil {
return nil, fmt.Errorf("go-jose/go-jose: protected header: %s", err)
}
}
if obj.unprotected != nil {
err := validateAlgEnc(*obj.unprotected, keyEncryptionAlgorithms, contentEncryption)
if err != nil {
return nil, fmt.Errorf("go-jose/go-jose: unprotected header: %s", err)
} }
} }
@ -200,34 +268,52 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) {
return obj, nil return obj, nil
} }
// parseEncryptedCompact parses a message in compact format. func validateAlgEnc(headers rawHeader, keyAlgorithms []KeyAlgorithm, contentEncryption []ContentEncryption) error {
func parseEncryptedCompact(input string) (*JSONWebEncryption, error) { alg := headers.getAlgorithm()
enc := headers.getEncryption()
if alg != "" && !containsKeyAlgorithm(keyAlgorithms, alg) {
return fmt.Errorf("unexpected key algorithm %q; expected %q", alg, keyAlgorithms)
}
if alg != "" && !containsContentEncryption(contentEncryption, enc) {
return fmt.Errorf("unexpected content encryption algorithm %q; expected %q", enc, contentEncryption)
}
return nil
}
// ParseEncryptedCompact parses a message in JWE Compact Serialization.
//
// https://datatracker.ietf.org/doc/html/rfc7516#section-3.1
func ParseEncryptedCompact(
input string,
keyAlgorithms []KeyAlgorithm,
contentEncryption []ContentEncryption,
) (*JSONWebEncryption, error) {
parts := strings.Split(input, ".") parts := strings.Split(input, ".")
if len(parts) != 5 { if len(parts) != 5 {
return nil, fmt.Errorf("go-jose/go-jose: compact JWE format must have five parts") return nil, fmt.Errorf("go-jose/go-jose: compact JWE format must have five parts")
} }
rawProtected, err := base64URLDecode(parts[0]) rawProtected, err := base64.RawURLEncoding.DecodeString(parts[0])
if err != nil { if err != nil {
return nil, err return nil, err
} }
encryptedKey, err := base64URLDecode(parts[1]) encryptedKey, err := base64.RawURLEncoding.DecodeString(parts[1])
if err != nil { if err != nil {
return nil, err return nil, err
} }
iv, err := base64URLDecode(parts[2]) iv, err := base64.RawURLEncoding.DecodeString(parts[2])
if err != nil { if err != nil {
return nil, err return nil, err
} }
ciphertext, err := base64URLDecode(parts[3]) ciphertext, err := base64.RawURLEncoding.DecodeString(parts[3])
if err != nil { if err != nil {
return nil, err return nil, err
} }
tag, err := base64URLDecode(parts[4]) tag, err := base64.RawURLEncoding.DecodeString(parts[4])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -240,7 +326,7 @@ func parseEncryptedCompact(input string) (*JSONWebEncryption, error) {
Tag: newBuffer(tag), Tag: newBuffer(tag),
} }
return raw.sanitized() return raw.sanitized(keyAlgorithms, contentEncryption)
} }
// CompactSerialize serializes an object using the compact serialization format. // CompactSerialize serializes an object using the compact serialization format.
@ -252,13 +338,13 @@ func (obj JSONWebEncryption) CompactSerialize() (string, error) {
serializedProtected := mustSerializeJSON(obj.protected) serializedProtected := mustSerializeJSON(obj.protected)
return fmt.Sprintf( return base64JoinWithDots(
"%s.%s.%s.%s.%s", serializedProtected,
base64.RawURLEncoding.EncodeToString(serializedProtected), obj.recipients[0].encryptedKey,
base64.RawURLEncoding.EncodeToString(obj.recipients[0].encryptedKey), obj.iv,
base64.RawURLEncoding.EncodeToString(obj.iv), obj.ciphertext,
base64.RawURLEncoding.EncodeToString(obj.ciphertext), obj.tag,
base64.RawURLEncoding.EncodeToString(obj.tag)), nil ), nil
} }
// FullSerialize serializes an object using the full JSON serialization format. // FullSerialize serializes an object using the full JSON serialization format.

View File

@ -35,7 +35,7 @@ import (
"reflect" "reflect"
"strings" "strings"
"github.com/go-jose/go-jose/v3/json" "github.com/go-jose/go-jose/v4/json"
) )
// rawJSONWebKey represents a public or private key in JWK format, used for parsing/serializing. // rawJSONWebKey represents a public or private key in JWK format, used for parsing/serializing.
@ -67,9 +67,21 @@ type rawJSONWebKey struct {
X5tSHA256 string `json:"x5t#S256,omitempty"` X5tSHA256 string `json:"x5t#S256,omitempty"`
} }
// JSONWebKey represents a public or private key in JWK format. // JSONWebKey represents a public or private key in JWK format. It can be
// marshaled into JSON and unmarshaled from JSON.
type JSONWebKey struct { type JSONWebKey struct {
// Cryptographic key, can be a symmetric or asymmetric key. // Key is the Go in-memory representation of this key. It must have one
// of these types:
// - ed25519.PublicKey
// - ed25519.PrivateKey
// - *ecdsa.PublicKey
// - *ecdsa.PrivateKey
// - *rsa.PublicKey
// - *rsa.PrivateKey
// - []byte (a symmetric key)
//
// When marshaling this JSONWebKey into JSON, the "kty" header parameter
// will be automatically set based on the type of this field.
Key interface{} Key interface{}
// Key identifier, parsed from `kid` header. // Key identifier, parsed from `kid` header.
KeyID string KeyID string
@ -254,7 +266,7 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
// x5t parameters are base64url-encoded SHA thumbprints // x5t parameters are base64url-encoded SHA thumbprints
// See RFC 7517, Section 4.8, https://tools.ietf.org/html/rfc7517#section-4.8 // See RFC 7517, Section 4.8, https://tools.ietf.org/html/rfc7517#section-4.8
x5tSHA1bytes, err := base64URLDecode(raw.X5tSHA1) x5tSHA1bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA1)
if err != nil { if err != nil {
return errors.New("go-jose/go-jose: invalid JWK, x5t header has invalid encoding") return errors.New("go-jose/go-jose: invalid JWK, x5t header has invalid encoding")
} }
@ -274,7 +286,7 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
k.CertificateThumbprintSHA1 = x5tSHA1bytes k.CertificateThumbprintSHA1 = x5tSHA1bytes
x5tSHA256bytes, err := base64URLDecode(raw.X5tSHA256) x5tSHA256bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA256)
if err != nil { if err != nil {
return errors.New("go-jose/go-jose: invalid JWK, x5t#S256 header has invalid encoding") return errors.New("go-jose/go-jose: invalid JWK, x5t#S256 header has invalid encoding")
} }
@ -389,6 +401,8 @@ func (k *JSONWebKey) Thumbprint(hash crypto.Hash) ([]byte, error) {
input, err = rsaThumbprintInput(key.N, key.E) input, err = rsaThumbprintInput(key.N, key.E)
case ed25519.PrivateKey: case ed25519.PrivateKey:
input, err = edThumbprintInput(ed25519.PublicKey(key[32:])) input, err = edThumbprintInput(ed25519.PublicKey(key[32:]))
case OpaqueSigner:
return key.Public().Thumbprint(hash)
default: default:
return nil, fmt.Errorf("go-jose/go-jose: unknown key type '%s'", reflect.TypeOf(key)) return nil, fmt.Errorf("go-jose/go-jose: unknown key type '%s'", reflect.TypeOf(key))
} }

View File

@ -23,7 +23,7 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/go-jose/go-jose/v3/json" "github.com/go-jose/go-jose/v4/json"
) )
// rawJSONWebSignature represents a raw JWS JSON object. Used for parsing/serializing. // rawJSONWebSignature represents a raw JWS JSON object. Used for parsing/serializing.
@ -75,22 +75,41 @@ type Signature struct {
original *rawSignatureInfo original *rawSignatureInfo
} }
// ParseSigned parses a signed message in compact or JWS JSON Serialization format. // ParseSigned parses a signed message in JWS Compact or JWS JSON Serialization.
func ParseSigned(signature string) (*JSONWebSignature, error) { //
// https://datatracker.ietf.org/doc/html/rfc7515#section-7
func ParseSigned(
signature string,
signatureAlgorithms []SignatureAlgorithm,
) (*JSONWebSignature, error) {
signature = stripWhitespace(signature) signature = stripWhitespace(signature)
if strings.HasPrefix(signature, "{") { if strings.HasPrefix(signature, "{") {
return parseSignedFull(signature) return ParseSignedJSON(signature, signatureAlgorithms)
} }
return parseSignedCompact(signature, nil) return parseSignedCompact(signature, nil, signatureAlgorithms)
}
// ParseSignedCompact parses a message in JWS Compact Serialization.
//
// https://datatracker.ietf.org/doc/html/rfc7515#section-7.1
func ParseSignedCompact(
signature string,
signatureAlgorithms []SignatureAlgorithm,
) (*JSONWebSignature, error) {
return parseSignedCompact(signature, nil, signatureAlgorithms)
} }
// ParseDetached parses a signed message in compact serialization format with detached payload. // ParseDetached parses a signed message in compact serialization format with detached payload.
func ParseDetached(signature string, payload []byte) (*JSONWebSignature, error) { func ParseDetached(
signature string,
payload []byte,
signatureAlgorithms []SignatureAlgorithm,
) (*JSONWebSignature, error) {
if payload == nil { if payload == nil {
return nil, errors.New("go-jose/go-jose: nil payload") return nil, errors.New("go-jose/go-jose: nil payload")
} }
return parseSignedCompact(stripWhitespace(signature), payload) return parseSignedCompact(stripWhitespace(signature), payload, signatureAlgorithms)
} }
// Get a header value // Get a header value
@ -137,19 +156,36 @@ func (obj JSONWebSignature) computeAuthData(payload []byte, signature *Signature
return authData.Bytes(), nil return authData.Bytes(), nil
} }
// parseSignedFull parses a message in full format. // ParseSignedJSON parses a message in JWS JSON Serialization.
func parseSignedFull(input string) (*JSONWebSignature, error) { //
// https://datatracker.ietf.org/doc/html/rfc7515#section-7.2
func ParseSignedJSON(
input string,
signatureAlgorithms []SignatureAlgorithm,
) (*JSONWebSignature, error) {
var parsed rawJSONWebSignature var parsed rawJSONWebSignature
err := json.Unmarshal([]byte(input), &parsed) err := json.Unmarshal([]byte(input), &parsed)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return parsed.sanitized() return parsed.sanitized(signatureAlgorithms)
}
func containsSignatureAlgorithm(haystack []SignatureAlgorithm, needle SignatureAlgorithm) bool {
for _, algorithm := range haystack {
if algorithm == needle {
return true
}
}
return false
} }
// sanitized produces a cleaned-up JWS object from the raw JSON. // sanitized produces a cleaned-up JWS object from the raw JSON.
func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) { func (parsed *rawJSONWebSignature) sanitized(signatureAlgorithms []SignatureAlgorithm) (*JSONWebSignature, error) {
if len(signatureAlgorithms) == 0 {
return nil, errors.New("go-jose/go-jose: no signature algorithms specified")
}
if parsed.Payload == nil { if parsed.Payload == nil {
return nil, fmt.Errorf("go-jose/go-jose: missing payload in JWS message") return nil, fmt.Errorf("go-jose/go-jose: missing payload in JWS message")
} }
@ -198,6 +234,12 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) {
return nil, err return nil, err
} }
alg := SignatureAlgorithm(signature.Header.Algorithm)
if !containsSignatureAlgorithm(signatureAlgorithms, alg) {
return nil, fmt.Errorf("go-jose/go-jose: unexpected signature algorithm %q; expected %q",
alg, signatureAlgorithms)
}
if signature.header != nil { if signature.header != nil {
signature.Unprotected, err = signature.header.sanitized() signature.Unprotected, err = signature.header.sanitized()
if err != nil { if err != nil {
@ -241,6 +283,12 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) {
return nil, err return nil, err
} }
alg := SignatureAlgorithm(obj.Signatures[i].Header.Algorithm)
if !containsSignatureAlgorithm(signatureAlgorithms, alg) {
return nil, fmt.Errorf("go-jose/go-jose: unexpected signature algorithm %q; expected %q",
alg, signatureAlgorithms)
}
if obj.Signatures[i].header != nil { if obj.Signatures[i].header != nil {
obj.Signatures[i].Unprotected, err = obj.Signatures[i].header.sanitized() obj.Signatures[i].Unprotected, err = obj.Signatures[i].header.sanitized()
if err != nil { if err != nil {
@ -274,7 +322,11 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) {
} }
// parseSignedCompact parses a message in compact format. // parseSignedCompact parses a message in compact format.
func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error) { func parseSignedCompact(
input string,
payload []byte,
signatureAlgorithms []SignatureAlgorithm,
) (*JSONWebSignature, error) {
parts := strings.Split(input, ".") parts := strings.Split(input, ".")
if len(parts) != 3 { if len(parts) != 3 {
return nil, fmt.Errorf("go-jose/go-jose: compact JWS format must have three parts") return nil, fmt.Errorf("go-jose/go-jose: compact JWS format must have three parts")
@ -284,19 +336,19 @@ func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error)
return nil, fmt.Errorf("go-jose/go-jose: payload is not detached") return nil, fmt.Errorf("go-jose/go-jose: payload is not detached")
} }
rawProtected, err := base64URLDecode(parts[0]) rawProtected, err := base64.RawURLEncoding.DecodeString(parts[0])
if err != nil { if err != nil {
return nil, err return nil, err
} }
if payload == nil { if payload == nil {
payload, err = base64URLDecode(parts[1]) payload, err = base64.RawURLEncoding.DecodeString(parts[1])
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
signature, err := base64URLDecode(parts[2]) signature, err := base64.RawURLEncoding.DecodeString(parts[2])
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -306,7 +358,7 @@ func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error)
Protected: newBuffer(rawProtected), Protected: newBuffer(rawProtected),
Signature: newBuffer(signature), Signature: newBuffer(signature),
} }
return raw.sanitized() return raw.sanitized(signatureAlgorithms)
} }
func (obj JSONWebSignature) compactSerialize(detached bool) (string, error) { func (obj JSONWebSignature) compactSerialize(detached bool) (string, error) {
@ -314,15 +366,18 @@ func (obj JSONWebSignature) compactSerialize(detached bool) (string, error) {
return "", ErrNotSupported return "", ErrNotSupported
} }
serializedProtected := base64.RawURLEncoding.EncodeToString(mustSerializeJSON(obj.Signatures[0].protected)) serializedProtected := mustSerializeJSON(obj.Signatures[0].protected)
payload := ""
signature := base64.RawURLEncoding.EncodeToString(obj.Signatures[0].Signature)
var payload []byte
if !detached { if !detached {
payload = base64.RawURLEncoding.EncodeToString(obj.payload) payload = obj.payload
} }
return fmt.Sprintf("%s.%s.%s", serializedProtected, payload, signature), nil return base64JoinWithDots(
serializedProtected,
payload,
obj.Signatures[0].Signature,
), nil
} }
// CompactSerialize serializes an object using the compact serialization format. // CompactSerialize serializes an object using the compact serialization format.

View File

@ -21,13 +21,13 @@ import (
"bytes" "bytes"
"reflect" "reflect"
"github.com/go-jose/go-jose/v3/json" "github.com/go-jose/go-jose/v4/json"
"github.com/go-jose/go-jose/v3" "github.com/go-jose/go-jose/v4"
) )
// Builder is a utility for making JSON Web Tokens. Calls can be chained, and // Builder is a utility for making JSON Web Tokens. Calls can be chained, and
// errors are accumulated until the final call to CompactSerialize/FullSerialize. // errors are accumulated until the final call to Serialize.
type Builder interface { type Builder interface {
// Claims encodes claims into JWE/JWS form. Multiple calls will merge claims // Claims encodes claims into JWE/JWS form. Multiple calls will merge claims
// into single JSON object. If you are passing private claims, make sure to set // into single JSON object. If you are passing private claims, make sure to set
@ -36,15 +36,13 @@ type Builder interface {
Claims(i interface{}) Builder Claims(i interface{}) Builder
// Token builds a JSONWebToken from provided data. // Token builds a JSONWebToken from provided data.
Token() (*JSONWebToken, error) Token() (*JSONWebToken, error)
// FullSerialize serializes a token using the JWS/JWE JSON Serialization format. // Serialize serializes a token.
FullSerialize() (string, error) Serialize() (string, error)
// CompactSerialize serializes a token using the compact serialization format.
CompactSerialize() (string, error)
} }
// NestedBuilder is a utility for making Signed-Then-Encrypted JSON Web Tokens. // NestedBuilder is a utility for making Signed-Then-Encrypted JSON Web Tokens.
// Calls can be chained, and errors are accumulated until final call to // Calls can be chained, and errors are accumulated until final call to
// CompactSerialize/FullSerialize. // Serialize.
type NestedBuilder interface { type NestedBuilder interface {
// Claims encodes claims into JWE/JWS form. Multiple calls will merge claims // Claims encodes claims into JWE/JWS form. Multiple calls will merge claims
// into single JSON object. If you are passing private claims, make sure to set // into single JSON object. If you are passing private claims, make sure to set
@ -53,10 +51,8 @@ type NestedBuilder interface {
Claims(i interface{}) NestedBuilder Claims(i interface{}) NestedBuilder
// Token builds a NestedJSONWebToken from provided data. // Token builds a NestedJSONWebToken from provided data.
Token() (*NestedJSONWebToken, error) Token() (*NestedJSONWebToken, error)
// FullSerialize serializes a token using the JSON Serialization format. // Serialize serializes a token.
FullSerialize() (string, error) Serialize() (string, error)
// CompactSerialize serializes a token using the compact serialization format.
CompactSerialize() (string, error)
} }
type builder struct { type builder struct {
@ -194,7 +190,7 @@ func (b *signedBuilder) Token() (*JSONWebToken, error) {
return b.builder.token(sig.Verify, h) return b.builder.token(sig.Verify, h)
} }
func (b *signedBuilder) CompactSerialize() (string, error) { func (b *signedBuilder) Serialize() (string, error) {
sig, err := b.sign() sig, err := b.sign()
if err != nil { if err != nil {
return "", err return "", err
@ -203,15 +199,6 @@ func (b *signedBuilder) CompactSerialize() (string, error) {
return sig.CompactSerialize() return sig.CompactSerialize()
} }
func (b *signedBuilder) FullSerialize() (string, error) {
sig, err := b.sign()
if err != nil {
return "", err
}
return sig.FullSerialize(), nil
}
func (b *signedBuilder) sign() (*jose.JSONWebSignature, error) { func (b *signedBuilder) sign() (*jose.JSONWebSignature, error) {
if b.err != nil { if b.err != nil {
return nil, b.err return nil, b.err
@ -232,7 +219,7 @@ func (b *encryptedBuilder) Claims(i interface{}) Builder {
} }
} }
func (b *encryptedBuilder) CompactSerialize() (string, error) { func (b *encryptedBuilder) Serialize() (string, error) {
enc, err := b.encrypt() enc, err := b.encrypt()
if err != nil { if err != nil {
return "", err return "", err
@ -241,15 +228,6 @@ func (b *encryptedBuilder) CompactSerialize() (string, error) {
return enc.CompactSerialize() return enc.CompactSerialize()
} }
func (b *encryptedBuilder) FullSerialize() (string, error) {
enc, err := b.encrypt()
if err != nil {
return "", err
}
return enc.FullSerialize(), nil
}
func (b *encryptedBuilder) Token() (*JSONWebToken, error) { func (b *encryptedBuilder) Token() (*JSONWebToken, error) {
enc, err := b.encrypt() enc, err := b.encrypt()
if err != nil { if err != nil {
@ -280,6 +258,8 @@ func (b *nestedBuilder) Claims(i interface{}) NestedBuilder {
} }
} }
// Token produced a token suitable for serialization. It cannot be decrypted
// without serializing and then deserializing.
func (b *nestedBuilder) Token() (*NestedJSONWebToken, error) { func (b *nestedBuilder) Token() (*NestedJSONWebToken, error) {
enc, err := b.signAndEncrypt() enc, err := b.signAndEncrypt()
if err != nil { if err != nil {
@ -287,12 +267,13 @@ func (b *nestedBuilder) Token() (*NestedJSONWebToken, error) {
} }
return &NestedJSONWebToken{ return &NestedJSONWebToken{
allowedSignatureAlgorithms: nil,
enc: enc, enc: enc,
Headers: []jose.Header{enc.Header}, Headers: []jose.Header{enc.Header},
}, nil }, nil
} }
func (b *nestedBuilder) CompactSerialize() (string, error) { func (b *nestedBuilder) Serialize() (string, error) {
enc, err := b.signAndEncrypt() enc, err := b.signAndEncrypt()
if err != nil { if err != nil {
return "", err return "", err

View File

@ -21,7 +21,7 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/go-jose/go-jose/v3/json" "github.com/go-jose/go-jose/v4/json"
) )
// Claims represents public claim values (as specified in RFC 7519). // Claims represents public claim values (as specified in RFC 7519).
@ -119,7 +119,7 @@ func (s Audience) MarshalJSON() ([]byte, error) {
return json.Marshal([]string(s)) return json.Marshal([]string(s))
} }
//Contains checks whether a given string is included in the Audience // Contains checks whether a given string is included in the Audience
func (s Audience) Contains(v string) bool { func (s Audience) Contains(v string) bool {
for _, a := range s { for _, a := range s {
if a == v { if a == v {

View File

@ -15,8 +15,6 @@
*/ */
/* /*
Package jwt provides an implementation of the JSON Web Token standard. Package jwt provides an implementation of the JSON Web Token standard.
*/ */
package jwt package jwt

198
vendor/github.com/go-jose/go-jose/v4/jwt/jwt.go generated vendored Normal file
View File

@ -0,0 +1,198 @@
/*-
* Copyright 2016 Zbigniew Mandziejewicz
* Copyright 2016 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jwt
import (
"fmt"
"strings"
jose "github.com/go-jose/go-jose/v4"
"github.com/go-jose/go-jose/v4/json"
)
// JSONWebToken represents a JSON Web Token (as specified in RFC7519).
type JSONWebToken struct {
payload func(k interface{}) ([]byte, error)
unverifiedPayload func() []byte
Headers []jose.Header
}
type NestedJSONWebToken struct {
enc *jose.JSONWebEncryption
Headers []jose.Header
// Used when parsing and decrypting an input
allowedSignatureAlgorithms []jose.SignatureAlgorithm
}
// Claims deserializes a JSONWebToken into dest using the provided key.
func (t *JSONWebToken) Claims(key interface{}, dest ...interface{}) error {
b, err := t.payload(key)
if err != nil {
return err
}
for _, d := range dest {
if err := json.Unmarshal(b, d); err != nil {
return err
}
}
return nil
}
// UnsafeClaimsWithoutVerification deserializes the claims of a
// JSONWebToken into the dests. For signed JWTs, the claims are not
// verified. This function won't work for encrypted JWTs.
func (t *JSONWebToken) UnsafeClaimsWithoutVerification(dest ...interface{}) error {
if t.unverifiedPayload == nil {
return fmt.Errorf("go-jose/go-jose: Cannot get unverified claims")
}
claims := t.unverifiedPayload()
for _, d := range dest {
if err := json.Unmarshal(claims, d); err != nil {
return err
}
}
return nil
}
func (t *NestedJSONWebToken) Decrypt(decryptionKey interface{}) (*JSONWebToken, error) {
b, err := t.enc.Decrypt(decryptionKey)
if err != nil {
return nil, err
}
sig, err := ParseSigned(string(b), t.allowedSignatureAlgorithms)
if err != nil {
return nil, err
}
return sig, nil
}
// ParseSigned parses token from JWS form.
func ParseSigned(s string, signatureAlgorithms []jose.SignatureAlgorithm) (*JSONWebToken, error) {
sig, err := jose.ParseSignedCompact(s, signatureAlgorithms)
if err != nil {
return nil, err
}
headers := make([]jose.Header, len(sig.Signatures))
for i, signature := range sig.Signatures {
headers[i] = signature.Header
}
return &JSONWebToken{
payload: sig.Verify,
unverifiedPayload: sig.UnsafePayloadWithoutVerification,
Headers: headers,
}, nil
}
func validateKeyEncryptionAlgorithm(algs []jose.KeyAlgorithm) error {
for _, alg := range algs {
switch alg {
case jose.ED25519,
jose.RSA1_5,
jose.RSA_OAEP,
jose.RSA_OAEP_256,
jose.ECDH_ES,
jose.ECDH_ES_A128KW,
jose.ECDH_ES_A192KW,
jose.ECDH_ES_A256KW:
return fmt.Errorf("asymmetric encryption algorithms not supported for JWT: "+
"invalid key encryption algorithm: %s", alg)
case jose.PBES2_HS256_A128KW,
jose.PBES2_HS384_A192KW,
jose.PBES2_HS512_A256KW:
return fmt.Errorf("password-based encryption not supported for JWT: "+
"invalid key encryption algorithm: %s", alg)
}
}
return nil
}
func parseEncryptedCompact(
s string,
keyAlgorithms []jose.KeyAlgorithm,
contentEncryption []jose.ContentEncryption,
) (*jose.JSONWebEncryption, error) {
err := validateKeyEncryptionAlgorithm(keyAlgorithms)
if err != nil {
return nil, err
}
enc, err := jose.ParseEncryptedCompact(s, keyAlgorithms, contentEncryption)
if err != nil {
return nil, err
}
return enc, nil
}
// ParseEncrypted parses token from JWE form.
//
// The keyAlgorithms and contentEncryption parameters are used to validate the "alg" and "enc"
// header parameters respectively. They must be nonempty, and each "alg" or "enc" header in
// parsed data must contain a value that is present in the corresponding parameter. That
// includes the protected and unprotected headers as well as all recipients. To accept
// multiple algorithms, pass a slice of all the algorithms you want to accept.
func ParseEncrypted(s string,
keyAlgorithms []jose.KeyAlgorithm,
contentEncryption []jose.ContentEncryption,
) (*JSONWebToken, error) {
enc, err := parseEncryptedCompact(s, keyAlgorithms, contentEncryption)
if err != nil {
return nil, err
}
return &JSONWebToken{
payload: enc.Decrypt,
Headers: []jose.Header{enc.Header},
}, nil
}
// ParseSignedAndEncrypted parses signed-then-encrypted token from JWE form.
//
// The encryptionKeyAlgorithms and contentEncryption parameters are used to validate the "alg" and "enc"
// header parameters, respectively, of the outer JWE. They must be nonempty, and each "alg" or "enc"
// header in parsed data must contain a value that is present in the corresponding parameter. That
// includes the protected and unprotected headers as well as all recipients. To accept
// multiple algorithms, pass a slice of all the algorithms you want to accept.
//
// The signatureAlgorithms parameter is used to validate the "alg" header parameter of the
// inner JWS. It must be nonempty, and the "alg" header in the inner JWS must contain a value
// that is present in the parameter.
func ParseSignedAndEncrypted(s string,
encryptionKeyAlgorithms []jose.KeyAlgorithm,
contentEncryption []jose.ContentEncryption,
signatureAlgorithms []jose.SignatureAlgorithm,
) (*NestedJSONWebToken, error) {
enc, err := parseEncryptedCompact(s, encryptionKeyAlgorithms, contentEncryption)
if err != nil {
return nil, err
}
contentType, _ := enc.Header.ExtraHeaders[jose.HeaderContentType].(string)
if strings.ToUpper(contentType) != "JWT" {
return nil, ErrInvalidContentType
}
return &NestedJSONWebToken{
allowedSignatureAlgorithms: signatureAlgorithms,
enc: enc,
Headers: []jose.Header{enc.Header},
}, nil
}

View File

@ -33,8 +33,9 @@ type Expected struct {
Issuer string Issuer string
// Subject matches the "sub" claim exactly. // Subject matches the "sub" claim exactly.
Subject string Subject string
// Audience matches the values in "aud" claim, regardless of their order. // AnyAudience matches if there is a non-empty intersection between
Audience Audience // its values and the values in the "aud" claim.
AnyAudience Audience
// ID matches the "jti" claim exactly. // ID matches the "jti" claim exactly.
ID string ID string
// Time matches the "exp", "nbf" and "iat" claims with leeway. // Time matches the "exp", "nbf" and "iat" claims with leeway.
@ -88,12 +89,18 @@ func (c Claims) ValidateWithLeeway(e Expected, leeway time.Duration) error {
return ErrInvalidID return ErrInvalidID
} }
if len(e.Audience) != 0 { if len(e.AnyAudience) != 0 {
for _, v := range e.Audience { var intersection bool
if !c.Audience.Contains(v) { for _, v := range e.AnyAudience {
return ErrInvalidAudience if c.Audience.Contains(v) {
intersection = true
break
} }
} }
if !intersection {
return ErrInvalidAudience
}
} }
// validate using the e.Time, or time.Now if not provided // validate using the e.Time, or time.Now if not provided

View File

@ -121,7 +121,7 @@ func (oke *opaqueKeyEncrypter) encryptKey(cek []byte, alg KeyAlgorithm) (recipie
return oke.encrypter.encryptKey(cek, alg) return oke.encrypter.encryptKey(cek, alg)
} }
//OpaqueKeyDecrypter is an interface that supports decrypting keys with an opaque key. // OpaqueKeyDecrypter is an interface that supports decrypting keys with an opaque key.
type OpaqueKeyDecrypter interface { type OpaqueKeyDecrypter interface {
DecryptKey(encryptedKey []byte, header Header) ([]byte, error) DecryptKey(encryptedKey []byte, header Header) ([]byte, error)
} }

View File

@ -23,7 +23,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/go-jose/go-jose/v3/json" "github.com/go-jose/go-jose/v4/json"
) )
// KeyAlgorithm represents a key management algorithm. // KeyAlgorithm represents a key management algorithm.
@ -183,8 +183,13 @@ type Header struct {
// Unverified certificate chain parsed from x5c header. // Unverified certificate chain parsed from x5c header.
certificates []*x509.Certificate certificates []*x509.Certificate
// Any headers not recognised above get unmarshalled // At parse time, each header parameter with a name other than "kid",
// from JSON in a generic manner and placed in this map. // "jwk", "alg", "nonce", or "x5c" will have its value passed to
// [json.Unmarshal] to unmarshal it into an interface value.
// The resulting value will be stored in this map, with the header
// parameter name as the key.
//
// [json.Unmarshal]: https://pkg.go.dev/encoding/json#Unmarshal
ExtraHeaders map[HeaderKey]interface{} ExtraHeaders map[HeaderKey]interface{}
} }

View File

@ -25,7 +25,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/go-jose/go-jose/v3/json" "github.com/go-jose/go-jose/v4/json"
) )
// NonceSource represents a source of random nonces to go into JWS objects // NonceSource represents a source of random nonces to go into JWS objects
@ -40,6 +40,20 @@ type Signer interface {
} }
// SigningKey represents an algorithm/key used to sign a message. // SigningKey represents an algorithm/key used to sign a message.
//
// Key must have one of these types:
// - ed25519.PrivateKey
// - *ecdsa.PrivateKey
// - *rsa.PrivateKey
// - *JSONWebKey
// - JSONWebKey
// - []byte (an HMAC key)
// - Any type that satisfies the OpaqueSigner interface
//
// If the key is an HMAC key, it must have at least as many bytes as the relevant hash output:
// - HS256: 32 bytes
// - HS384: 48 bytes
// - HS512: 64 bytes
type SigningKey struct { type SigningKey struct {
Algorithm SignatureAlgorithm Algorithm SignatureAlgorithm
Key interface{} Key interface{}
@ -52,12 +66,22 @@ type SignerOptions struct {
// Optional map of additional keys to be inserted into the protected header // Optional map of additional keys to be inserted into the protected header
// of a JWS object. Some specifications which make use of JWS like to insert // of a JWS object. Some specifications which make use of JWS like to insert
// additional values here. All values must be JSON-serializable. // additional values here.
//
// Values will be serialized by [json.Marshal] and must be valid inputs to
// that function.
//
// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal
ExtraHeaders map[HeaderKey]interface{} ExtraHeaders map[HeaderKey]interface{}
} }
// WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it // WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it
// if necessary. It returns itself and so can be used in a fluent style. // if necessary, and returns the updated SignerOptions.
//
// The v argument will be serialized by [json.Marshal] and must be a valid
// input to that function.
//
// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal
func (so *SignerOptions) WithHeader(k HeaderKey, v interface{}) *SignerOptions { func (so *SignerOptions) WithHeader(k HeaderKey, v interface{}) *SignerOptions {
if so.ExtraHeaders == nil { if so.ExtraHeaders == nil {
so.ExtraHeaders = map[HeaderKey]interface{}{} so.ExtraHeaders = map[HeaderKey]interface{}{}
@ -173,11 +197,11 @@ func newVerifier(verificationKey interface{}) (payloadVerifier, error) {
return newVerifier(verificationKey.Key) return newVerifier(verificationKey.Key)
case *JSONWebKey: case *JSONWebKey:
return newVerifier(verificationKey.Key) return newVerifier(verificationKey.Key)
} case OpaqueVerifier:
if ov, ok := verificationKey.(OpaqueVerifier); ok { return &opaqueVerifier{verifier: verificationKey}, nil
return &opaqueVerifier{verifier: ov}, nil default:
}
return nil, ErrUnsupportedKeyType return nil, ErrUnsupportedKeyType
}
} }
func (ctx *genericSigner) addRecipient(alg SignatureAlgorithm, signingKey interface{}) error { func (ctx *genericSigner) addRecipient(alg SignatureAlgorithm, signingKey interface{}) error {
@ -204,11 +228,11 @@ func makeJWSRecipient(alg SignatureAlgorithm, signingKey interface{}) (recipient
return newJWKSigner(alg, signingKey) return newJWKSigner(alg, signingKey)
case *JSONWebKey: case *JSONWebKey:
return newJWKSigner(alg, *signingKey) return newJWKSigner(alg, *signingKey)
} case OpaqueSigner:
if signer, ok := signingKey.(OpaqueSigner); ok { return newOpaqueSigner(alg, signingKey)
return newOpaqueSigner(alg, signer) default:
}
return recipientSigInfo{}, ErrUnsupportedKeyType return recipientSigInfo{}, ErrUnsupportedKeyType
}
} }
func newJWKSigner(alg SignatureAlgorithm, signingKey JSONWebKey) (recipientSigInfo, error) { func newJWKSigner(alg SignatureAlgorithm, signingKey JSONWebKey) (recipientSigInfo, error) {
@ -321,12 +345,26 @@ func (ctx *genericSigner) Options() SignerOptions {
} }
// Verify validates the signature on the object and returns the payload. // Verify validates the signature on the object and returns the payload.
// This function does not support multi-signature, if you desire multi-sig // This function does not support multi-signature. If you desire multi-signature
// verification use VerifyMulti instead. // verification use VerifyMulti instead.
// //
// Be careful when verifying signatures based on embedded JWKs inside the // Be careful when verifying signatures based on embedded JWKs inside the
// payload header. You cannot assume that the key received in a payload is // payload header. You cannot assume that the key received in a payload is
// trusted. // trusted.
//
// The verificationKey argument must have one of these types:
// - ed25519.PublicKey
// - *ecdsa.PublicKey
// - *rsa.PublicKey
// - *JSONWebKey
// - JSONWebKey
// - []byte (an HMAC key)
// - Any type that implements the OpaqueVerifier interface.
//
// If the key is an HMAC key, it must have at least as many bytes as the relevant hash output:
// - HS256: 32 bytes
// - HS384: 48 bytes
// - HS512: 64 bytes
func (obj JSONWebSignature) Verify(verificationKey interface{}) ([]byte, error) { func (obj JSONWebSignature) Verify(verificationKey interface{}) ([]byte, error) {
err := obj.DetachedVerify(obj.payload, verificationKey) err := obj.DetachedVerify(obj.payload, verificationKey)
if err != nil { if err != nil {
@ -346,6 +384,9 @@ func (obj JSONWebSignature) UnsafePayloadWithoutVerification() []byte {
// most cases, you will probably want to use Verify instead. DetachedVerify // most cases, you will probably want to use Verify instead. DetachedVerify
// is only useful if you have a payload and signature that are separated from // is only useful if you have a payload and signature that are separated from
// each other. // each other.
//
// The verificationKey argument must have one of the types allowed for the
// verificationKey argument of JSONWebSignature.Verify().
func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey interface{}) error { func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey interface{}) error {
key := tryJWKS(verificationKey, obj.headers()...) key := tryJWKS(verificationKey, obj.headers()...)
verifier, err := newVerifier(key) verifier, err := newVerifier(key)
@ -388,6 +429,9 @@ func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey inter
// returns the index of the signature that was verified, along with the signature // returns the index of the signature that was verified, along with the signature
// object and the payload. We return the signature and index to guarantee that // object and the payload. We return the signature and index to guarantee that
// callers are getting the verified value. // callers are getting the verified value.
//
// The verificationKey argument must have one of the types allowed for the
// verificationKey argument of JSONWebSignature.Verify().
func (obj JSONWebSignature) VerifyMulti(verificationKey interface{}) (int, Signature, []byte, error) { func (obj JSONWebSignature) VerifyMulti(verificationKey interface{}) (int, Signature, []byte, error) {
idx, sig, err := obj.DetachedVerifyMulti(obj.payload, verificationKey) idx, sig, err := obj.DetachedVerifyMulti(obj.payload, verificationKey)
if err != nil { if err != nil {
@ -405,6 +449,9 @@ func (obj JSONWebSignature) VerifyMulti(verificationKey interface{}) (int, Signa
// DetachedVerifyMulti is only useful if you have a payload and signature that are // DetachedVerifyMulti is only useful if you have a payload and signature that are
// separated from each other, and the signature can have multiple signers at the // separated from each other, and the signature can have multiple signers at the
// same time. // same time.
//
// The verificationKey argument must have one of the types allowed for the
// verificationKey argument of JSONWebSignature.Verify().
func (obj JSONWebSignature) DetachedVerifyMulti(payload []byte, verificationKey interface{}) (int, Signature, error) { func (obj JSONWebSignature) DetachedVerifyMulti(payload []byte, verificationKey interface{}) (int, Signature, error) {
key := tryJWKS(verificationKey, obj.headers()...) key := tryJWKS(verificationKey, obj.headers()...)
verifier, err := newVerifier(key) verifier, err := newVerifier(key)

View File

@ -32,7 +32,7 @@ import (
"golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/pbkdf2"
josecipher "github.com/go-jose/go-jose/v3/cipher" josecipher "github.com/go-jose/go-jose/v4/cipher"
) )
// RandReader is a cryptographically secure random number generator (stubbed out in tests). // RandReader is a cryptographically secure random number generator (stubbed out in tests).
@ -40,12 +40,17 @@ var RandReader = rand.Reader
const ( const (
// RFC7518 recommends a minimum of 1,000 iterations: // RFC7518 recommends a minimum of 1,000 iterations:
// https://tools.ietf.org/html/rfc7518#section-4.8.1.2 // - https://tools.ietf.org/html/rfc7518#section-4.8.1.2
//
// NIST recommends a minimum of 10,000: // NIST recommends a minimum of 10,000:
// https://pages.nist.gov/800-63-3/sp800-63b.html // - https://pages.nist.gov/800-63-3/sp800-63b.html
// 1Password uses 100,000: //
// https://support.1password.com/pbkdf2/ // 1Password increased in 2023 from 100,000 to 650,000:
defaultP2C = 100000 // - https://support.1password.com/pbkdf2/
//
// OWASP recommended 600,000 in Dec 2022:
// - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2
defaultP2C = 600000
// Default salt size: 128 bits // Default salt size: 128 bits
defaultP2SSize = 16 defaultP2SSize = 16
) )
@ -415,6 +420,11 @@ func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipien
if p2c <= 0 { if p2c <= 0 {
return nil, fmt.Errorf("go-jose/go-jose: invalid P2C: must be a positive integer") return nil, fmt.Errorf("go-jose/go-jose: invalid P2C: must be a positive integer")
} }
if p2c > 1000000 {
// An unauthenticated attacker can set a high P2C value. Set an upper limit to avoid
// DoS attacks.
return nil, fmt.Errorf("go-jose/go-jose: invalid P2C: too high")
}
// salt is UTF8(Alg) || 0x00 || Salt Input // salt is UTF8(Alg) || 0x00 || Salt Input
alg := headers.getAlgorithm() alg := headers.getAlgorithm()
@ -444,7 +454,7 @@ func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipien
func (ctx symmetricMac) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) { func (ctx symmetricMac) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
mac, err := ctx.hmac(payload, alg) mac, err := ctx.hmac(payload, alg)
if err != nil { if err != nil {
return Signature{}, errors.New("go-jose/go-jose: failed to compute hmac") return Signature{}, err
} }
return Signature{ return Signature{
@ -476,12 +486,24 @@ func (ctx symmetricMac) verifyPayload(payload []byte, mac []byte, alg SignatureA
func (ctx symmetricMac) hmac(payload []byte, alg SignatureAlgorithm) ([]byte, error) { func (ctx symmetricMac) hmac(payload []byte, alg SignatureAlgorithm) ([]byte, error) {
var hash func() hash.Hash var hash func() hash.Hash
// https://datatracker.ietf.org/doc/html/rfc7518#section-3.2
// A key of the same size as the hash output (for instance, 256 bits for
// "HS256") or larger MUST be used
switch alg { switch alg {
case HS256: case HS256:
if len(ctx.key)*8 < 256 {
return nil, ErrInvalidKeySize
}
hash = sha256.New hash = sha256.New
case HS384: case HS384:
if len(ctx.key)*8 < 384 {
return nil, ErrInvalidKeySize
}
hash = sha512.New384 hash = sha512.New384
case HS512: case HS512:
if len(ctx.key)*8 < 512 {
return nil, ErrInvalidKeySize
}
hash = sha512.New hash = sha512.New
default: default:
return nil, ErrUnsupportedAlgorithm return nil, ErrUnsupportedAlgorithm

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build go1.7 && amd64 && gc && !purego //go:build amd64 && gc && !purego
package blake2b package blake2b

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build go1.7 && amd64 && gc && !purego //go:build amd64 && gc && !purego
#include "textflag.h" #include "textflag.h"

View File

@ -1,24 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !go1.7 && amd64 && gc && !purego
package blake2b
import "golang.org/x/sys/cpu"
func init() {
useSSE4 = cpu.X86.HasSSE41
}
//go:noescape
func hashBlocksSSE4(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte)
func hashBlocks(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
if useSSE4 {
hashBlocksSSE4(h, c, flag, blocks)
} else {
hashBlocksGeneric(h, c, flag, blocks)
}
}

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build go1.9
package blake2b package blake2b
import ( import (

View File

@ -1,39 +0,0 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !go1.13
package poly1305
// Generic fallbacks for the math/bits intrinsics, copied from
// src/math/bits/bits.go. They were added in Go 1.12, but Add64 and Sum64 had
// variable time fallbacks until Go 1.13.
func bitsAdd64(x, y, carry uint64) (sum, carryOut uint64) {
sum = x + y + carry
carryOut = ((x & y) | ((x | y) &^ sum)) >> 63
return
}
func bitsSub64(x, y, borrow uint64) (diff, borrowOut uint64) {
diff = x - y - borrow
borrowOut = ((^x & y) | (^(x ^ y) & diff)) >> 63
return
}
func bitsMul64(x, y uint64) (hi, lo uint64) {
const mask32 = 1<<32 - 1
x0 := x & mask32
x1 := x >> 32
y0 := y & mask32
y1 := y >> 32
w0 := x0 * y0
t := x1*y0 + w0>>32
w1 := t & mask32
w2 := t >> 32
w1 += x0 * y1
hi = x1*y1 + w2 + w1>>32
lo = x * y
return
}

View File

@ -1,21 +0,0 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build go1.13
package poly1305
import "math/bits"
func bitsAdd64(x, y, carry uint64) (sum, carryOut uint64) {
return bits.Add64(x, y, carry)
}
func bitsSub64(x, y, borrow uint64) (diff, borrowOut uint64) {
return bits.Sub64(x, y, borrow)
}
func bitsMul64(x, y uint64) (hi, lo uint64) {
return bits.Mul64(x, y)
}

View File

@ -7,7 +7,10 @@
package poly1305 package poly1305
import "encoding/binary" import (
"encoding/binary"
"math/bits"
)
// Poly1305 [RFC 7539] is a relatively simple algorithm: the authentication tag // Poly1305 [RFC 7539] is a relatively simple algorithm: the authentication tag
// for a 64 bytes message is approximately // for a 64 bytes message is approximately
@ -114,13 +117,13 @@ type uint128 struct {
} }
func mul64(a, b uint64) uint128 { func mul64(a, b uint64) uint128 {
hi, lo := bitsMul64(a, b) hi, lo := bits.Mul64(a, b)
return uint128{lo, hi} return uint128{lo, hi}
} }
func add128(a, b uint128) uint128 { func add128(a, b uint128) uint128 {
lo, c := bitsAdd64(a.lo, b.lo, 0) lo, c := bits.Add64(a.lo, b.lo, 0)
hi, c := bitsAdd64(a.hi, b.hi, c) hi, c := bits.Add64(a.hi, b.hi, c)
if c != 0 { if c != 0 {
panic("poly1305: unexpected overflow") panic("poly1305: unexpected overflow")
} }
@ -155,8 +158,8 @@ func updateGeneric(state *macState, msg []byte) {
// hide leading zeroes. For full chunks, that's 1 << 128, so we can just // hide leading zeroes. For full chunks, that's 1 << 128, so we can just
// add 1 to the most significant (2¹²⁸) limb, h2. // add 1 to the most significant (2¹²⁸) limb, h2.
if len(msg) >= TagSize { if len(msg) >= TagSize {
h0, c = bitsAdd64(h0, binary.LittleEndian.Uint64(msg[0:8]), 0) h0, c = bits.Add64(h0, binary.LittleEndian.Uint64(msg[0:8]), 0)
h1, c = bitsAdd64(h1, binary.LittleEndian.Uint64(msg[8:16]), c) h1, c = bits.Add64(h1, binary.LittleEndian.Uint64(msg[8:16]), c)
h2 += c + 1 h2 += c + 1
msg = msg[TagSize:] msg = msg[TagSize:]
@ -165,8 +168,8 @@ func updateGeneric(state *macState, msg []byte) {
copy(buf[:], msg) copy(buf[:], msg)
buf[len(msg)] = 1 buf[len(msg)] = 1
h0, c = bitsAdd64(h0, binary.LittleEndian.Uint64(buf[0:8]), 0) h0, c = bits.Add64(h0, binary.LittleEndian.Uint64(buf[0:8]), 0)
h1, c = bitsAdd64(h1, binary.LittleEndian.Uint64(buf[8:16]), c) h1, c = bits.Add64(h1, binary.LittleEndian.Uint64(buf[8:16]), c)
h2 += c h2 += c
msg = nil msg = nil
@ -219,9 +222,9 @@ func updateGeneric(state *macState, msg []byte) {
m3 := h2r1 m3 := h2r1
t0 := m0.lo t0 := m0.lo
t1, c := bitsAdd64(m1.lo, m0.hi, 0) t1, c := bits.Add64(m1.lo, m0.hi, 0)
t2, c := bitsAdd64(m2.lo, m1.hi, c) t2, c := bits.Add64(m2.lo, m1.hi, c)
t3, _ := bitsAdd64(m3.lo, m2.hi, c) t3, _ := bits.Add64(m3.lo, m2.hi, c)
// Now we have the result as 4 64-bit limbs, and we need to reduce it // Now we have the result as 4 64-bit limbs, and we need to reduce it
// modulo 2¹³⁰ - 5. The special shape of this Crandall prime lets us do // modulo 2¹³⁰ - 5. The special shape of this Crandall prime lets us do
@ -243,14 +246,14 @@ func updateGeneric(state *macState, msg []byte) {
// To add c * 5 to h, we first add cc = c * 4, and then add (cc >> 2) = c. // To add c * 5 to h, we first add cc = c * 4, and then add (cc >> 2) = c.
h0, c = bitsAdd64(h0, cc.lo, 0) h0, c = bits.Add64(h0, cc.lo, 0)
h1, c = bitsAdd64(h1, cc.hi, c) h1, c = bits.Add64(h1, cc.hi, c)
h2 += c h2 += c
cc = shiftRightBy2(cc) cc = shiftRightBy2(cc)
h0, c = bitsAdd64(h0, cc.lo, 0) h0, c = bits.Add64(h0, cc.lo, 0)
h1, c = bitsAdd64(h1, cc.hi, c) h1, c = bits.Add64(h1, cc.hi, c)
h2 += c h2 += c
// h2 is at most 3 + 1 + 1 = 5, making the whole of h at most // h2 is at most 3 + 1 + 1 = 5, making the whole of h at most
@ -287,9 +290,9 @@ func finalize(out *[TagSize]byte, h *[3]uint64, s *[2]uint64) {
// in constant time, we compute t = h - (2¹³⁰ - 5), and select h as the // in constant time, we compute t = h - (2¹³⁰ - 5), and select h as the
// result if the subtraction underflows, and t otherwise. // result if the subtraction underflows, and t otherwise.
hMinusP0, b := bitsSub64(h0, p0, 0) hMinusP0, b := bits.Sub64(h0, p0, 0)
hMinusP1, b := bitsSub64(h1, p1, b) hMinusP1, b := bits.Sub64(h1, p1, b)
_, b = bitsSub64(h2, p2, b) _, b = bits.Sub64(h2, p2, b)
// h = h if h < p else h - p // h = h if h < p else h - p
h0 = select64(b, h0, hMinusP0) h0 = select64(b, h0, hMinusP0)
@ -301,8 +304,8 @@ func finalize(out *[TagSize]byte, h *[3]uint64, s *[2]uint64) {
// //
// by just doing a wide addition with the 128 low bits of h and discarding // by just doing a wide addition with the 128 low bits of h and discarding
// the overflow. // the overflow.
h0, c := bitsAdd64(h0, s[0], 0) h0, c := bits.Add64(h0, s[0], 0)
h1, _ = bitsAdd64(h1, s[1], c) h1, _ = bits.Add64(h1, s[1], c)
binary.LittleEndian.PutUint64(out[0:8], h0) binary.LittleEndian.PutUint64(out[0:8], h0)
binary.LittleEndian.PutUint64(out[8:16], h1) binary.LittleEndian.PutUint64(out[8:16], h1)

View File

@ -19,15 +19,14 @@
#define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3, t4, t5) \ #define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3, t4, t5) \
MULLD r0, h0, t0; \ MULLD r0, h0, t0; \
MULLD r0, h1, t4; \
MULHDU r0, h0, t1; \ MULHDU r0, h0, t1; \
MULLD r0, h1, t4; \
MULHDU r0, h1, t5; \ MULHDU r0, h1, t5; \
ADDC t4, t1, t1; \ ADDC t4, t1, t1; \
MULLD r0, h2, t2; \ MULLD r0, h2, t2; \
ADDZE t5; \
MULHDU r1, h0, t4; \ MULHDU r1, h0, t4; \
MULLD r1, h0, h0; \ MULLD r1, h0, h0; \
ADD t5, t2, t2; \ ADDE t5, t2, t2; \
ADDC h0, t1, t1; \ ADDC h0, t1, t1; \
MULLD h2, r1, t3; \ MULLD h2, r1, t3; \
ADDZE t4, h0; \ ADDZE t4, h0; \
@ -37,13 +36,11 @@
ADDE t5, t3, t3; \ ADDE t5, t3, t3; \
ADDC h0, t2, t2; \ ADDC h0, t2, t2; \
MOVD $-4, t4; \ MOVD $-4, t4; \
MOVD t0, h0; \
MOVD t1, h1; \
ADDZE t3; \ ADDZE t3; \
ANDCC $3, t2, h2; \ RLDICL $0, t2, $62, h2; \
AND t2, t4, t0; \ AND t2, t4, h0; \
ADDC t0, h0, h0; \ ADDC t0, h0, h0; \
ADDE t3, h1, h1; \ ADDE t3, t1, h1; \
SLD $62, t3, t4; \ SLD $62, t3, t4; \
SRD $2, t2; \ SRD $2, t2; \
ADDZE h2; \ ADDZE h2; \
@ -75,6 +72,7 @@ TEXT ·update(SB), $0-32
loop: loop:
POLY1305_ADD(R4, R8, R9, R10, R20, R21, R22) POLY1305_ADD(R4, R8, R9, R10, R20, R21, R22)
PCALIGN $16
multiply: multiply:
POLY1305_MUL(R8, R9, R10, R11, R12, R16, R17, R18, R14, R20, R21) POLY1305_MUL(R8, R9, R10, R11, R12, R16, R17, R18, R14, R20, R21)
ADD $-16, R5 ADD $-16, R5

View File

@ -187,9 +187,11 @@ type channel struct {
pending *buffer pending *buffer
extPending *buffer extPending *buffer
// windowMu protects myWindow, the flow-control window. // windowMu protects myWindow, the flow-control window, and myConsumed,
// the number of bytes consumed since we last increased myWindow
windowMu sync.Mutex windowMu sync.Mutex
myWindow uint32 myWindow uint32
myConsumed uint32
// writeMu serializes calls to mux.conn.writePacket() and // writeMu serializes calls to mux.conn.writePacket() and
// protects sentClose and packetPool. This mutex must be // protects sentClose and packetPool. This mutex must be
@ -332,14 +334,24 @@ func (ch *channel) handleData(packet []byte) error {
return nil return nil
} }
func (c *channel) adjustWindow(n uint32) error { func (c *channel) adjustWindow(adj uint32) error {
c.windowMu.Lock() c.windowMu.Lock()
// Since myWindow is managed on our side, and can never exceed // Since myConsumed and myWindow are managed on our side, and can never
// the initial window setting, we don't worry about overflow. // exceed the initial window setting, we don't worry about overflow.
c.myWindow += uint32(n) c.myConsumed += adj
var sendAdj uint32
if (channelWindowSize-c.myWindow > 3*c.maxIncomingPayload) ||
(c.myWindow < channelWindowSize/2) {
sendAdj = c.myConsumed
c.myConsumed = 0
c.myWindow += sendAdj
}
c.windowMu.Unlock() c.windowMu.Unlock()
if sendAdj == 0 {
return nil
}
return c.sendMessage(windowAdjustMsg{ return c.sendMessage(windowAdjustMsg{
AdditionalBytes: uint32(n), AdditionalBytes: sendAdj,
}) })
} }

View File

@ -82,7 +82,7 @@ func NewClientConn(c net.Conn, addr string, config *ClientConfig) (Conn, <-chan
if err := conn.clientHandshake(addr, &fullConf); err != nil { if err := conn.clientHandshake(addr, &fullConf); err != nil {
c.Close() c.Close()
return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %v", err) return nil, nil, nil, fmt.Errorf("ssh: handshake failed: %w", err)
} }
conn.mux = newMux(conn.transport) conn.mux = newMux(conn.transport)
return conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil return conn, conn.mux.incomingChannels, conn.mux.incomingRequests, nil

View File

@ -35,6 +35,16 @@ type keyingTransport interface {
// direction will be effected if a msgNewKeys message is sent // direction will be effected if a msgNewKeys message is sent
// or received. // or received.
prepareKeyChange(*algorithms, *kexResult) error prepareKeyChange(*algorithms, *kexResult) error
// setStrictMode sets the strict KEX mode, notably triggering
// sequence number resets on sending or receiving msgNewKeys.
// If the sequence number is already > 1 when setStrictMode
// is called, an error is returned.
setStrictMode() error
// setInitialKEXDone indicates to the transport that the initial key exchange
// was completed
setInitialKEXDone()
} }
// handshakeTransport implements rekeying on top of a keyingTransport // handshakeTransport implements rekeying on top of a keyingTransport
@ -100,6 +110,10 @@ type handshakeTransport struct {
// The session ID or nil if first kex did not complete yet. // The session ID or nil if first kex did not complete yet.
sessionID []byte sessionID []byte
// strictMode indicates if the other side of the handshake indicated
// that we should be following the strict KEX protocol restrictions.
strictMode bool
} }
type pendingKex struct { type pendingKex struct {
@ -209,7 +223,10 @@ func (t *handshakeTransport) readLoop() {
close(t.incoming) close(t.incoming)
break break
} }
if p[0] == msgIgnore || p[0] == msgDebug { // If this is the first kex, and strict KEX mode is enabled,
// we don't ignore any messages, as they may be used to manipulate
// the packet sequence numbers.
if !(t.sessionID == nil && t.strictMode) && (p[0] == msgIgnore || p[0] == msgDebug) {
continue continue
} }
t.incoming <- p t.incoming <- p
@ -441,6 +458,11 @@ func (t *handshakeTransport) readOnePacket(first bool) ([]byte, error) {
return successPacket, nil return successPacket, nil
} }
const (
kexStrictClient = "kex-strict-c-v00@openssh.com"
kexStrictServer = "kex-strict-s-v00@openssh.com"
)
// sendKexInit sends a key change message. // sendKexInit sends a key change message.
func (t *handshakeTransport) sendKexInit() error { func (t *handshakeTransport) sendKexInit() error {
t.mu.Lock() t.mu.Lock()
@ -454,7 +476,6 @@ func (t *handshakeTransport) sendKexInit() error {
} }
msg := &kexInitMsg{ msg := &kexInitMsg{
KexAlgos: t.config.KeyExchanges,
CiphersClientServer: t.config.Ciphers, CiphersClientServer: t.config.Ciphers,
CiphersServerClient: t.config.Ciphers, CiphersServerClient: t.config.Ciphers,
MACsClientServer: t.config.MACs, MACsClientServer: t.config.MACs,
@ -464,6 +485,13 @@ func (t *handshakeTransport) sendKexInit() error {
} }
io.ReadFull(rand.Reader, msg.Cookie[:]) io.ReadFull(rand.Reader, msg.Cookie[:])
// We mutate the KexAlgos slice, in order to add the kex-strict extension algorithm,
// and possibly to add the ext-info extension algorithm. Since the slice may be the
// user owned KeyExchanges, we create our own slice in order to avoid using user
// owned memory by mistake.
msg.KexAlgos = make([]string, 0, len(t.config.KeyExchanges)+2) // room for kex-strict and ext-info
msg.KexAlgos = append(msg.KexAlgos, t.config.KeyExchanges...)
isServer := len(t.hostKeys) > 0 isServer := len(t.hostKeys) > 0
if isServer { if isServer {
for _, k := range t.hostKeys { for _, k := range t.hostKeys {
@ -488,17 +516,24 @@ func (t *handshakeTransport) sendKexInit() error {
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, keyFormat) msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, keyFormat)
} }
} }
if t.sessionID == nil {
msg.KexAlgos = append(msg.KexAlgos, kexStrictServer)
}
} else { } else {
msg.ServerHostKeyAlgos = t.hostKeyAlgorithms msg.ServerHostKeyAlgos = t.hostKeyAlgorithms
// As a client we opt in to receiving SSH_MSG_EXT_INFO so we know what // As a client we opt in to receiving SSH_MSG_EXT_INFO so we know what
// algorithms the server supports for public key authentication. See RFC // algorithms the server supports for public key authentication. See RFC
// 8308, Section 2.1. // 8308, Section 2.1.
//
// We also send the strict KEX mode extension algorithm, in order to opt
// into the strict KEX mode.
if firstKeyExchange := t.sessionID == nil; firstKeyExchange { if firstKeyExchange := t.sessionID == nil; firstKeyExchange {
msg.KexAlgos = make([]string, 0, len(t.config.KeyExchanges)+1)
msg.KexAlgos = append(msg.KexAlgos, t.config.KeyExchanges...)
msg.KexAlgos = append(msg.KexAlgos, "ext-info-c") msg.KexAlgos = append(msg.KexAlgos, "ext-info-c")
msg.KexAlgos = append(msg.KexAlgos, kexStrictClient)
} }
} }
packet := Marshal(msg) packet := Marshal(msg)
@ -604,6 +639,13 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
return err return err
} }
if t.sessionID == nil && ((isClient && contains(serverInit.KexAlgos, kexStrictServer)) || (!isClient && contains(clientInit.KexAlgos, kexStrictClient))) {
t.strictMode = true
if err := t.conn.setStrictMode(); err != nil {
return err
}
}
// We don't send FirstKexFollows, but we handle receiving it. // We don't send FirstKexFollows, but we handle receiving it.
// //
// RFC 4253 section 7 defines the kex and the agreement method for // RFC 4253 section 7 defines the kex and the agreement method for
@ -679,6 +721,12 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
return unexpectedMessageError(msgNewKeys, packet[0]) return unexpectedMessageError(msgNewKeys, packet[0])
} }
if firstKeyExchange {
// Indicates to the transport that the first key exchange is completed
// after receiving SSH_MSG_NEWKEYS.
t.conn.setInitialKEXDone()
}
return nil return nil
} }

View File

@ -213,6 +213,7 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha
} else { } else {
for _, algo := range fullConf.PublicKeyAuthAlgorithms { for _, algo := range fullConf.PublicKeyAuthAlgorithms {
if !contains(supportedPubKeyAuthAlgos, algo) { if !contains(supportedPubKeyAuthAlgos, algo) {
c.Close()
return nil, nil, nil, fmt.Errorf("ssh: unsupported public key authentication algorithm %s", algo) return nil, nil, nil, fmt.Errorf("ssh: unsupported public key authentication algorithm %s", algo)
} }
} }
@ -220,6 +221,7 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha
// Check if the config contains any unsupported key exchanges // Check if the config contains any unsupported key exchanges
for _, kex := range fullConf.KeyExchanges { for _, kex := range fullConf.KeyExchanges {
if _, ok := serverForbiddenKexAlgos[kex]; ok { if _, ok := serverForbiddenKexAlgos[kex]; ok {
c.Close()
return nil, nil, nil, fmt.Errorf("ssh: unsupported key exchange %s for server", kex) return nil, nil, nil, fmt.Errorf("ssh: unsupported key exchange %s for server", kex)
} }
} }

View File

@ -49,6 +49,9 @@ type transport struct {
rand io.Reader rand io.Reader
isClient bool isClient bool
io.Closer io.Closer
strictMode bool
initialKEXDone bool
} }
// packetCipher represents a combination of SSH encryption/MAC // packetCipher represents a combination of SSH encryption/MAC
@ -74,6 +77,18 @@ type connectionState struct {
pendingKeyChange chan packetCipher pendingKeyChange chan packetCipher
} }
func (t *transport) setStrictMode() error {
if t.reader.seqNum != 1 {
return errors.New("ssh: sequence number != 1 when strict KEX mode requested")
}
t.strictMode = true
return nil
}
func (t *transport) setInitialKEXDone() {
t.initialKEXDone = true
}
// prepareKeyChange sets up key material for a keychange. The key changes in // prepareKeyChange sets up key material for a keychange. The key changes in
// both directions are triggered by reading and writing a msgNewKey packet // both directions are triggered by reading and writing a msgNewKey packet
// respectively. // respectively.
@ -112,11 +127,12 @@ func (t *transport) printPacket(p []byte, write bool) {
// Read and decrypt next packet. // Read and decrypt next packet.
func (t *transport) readPacket() (p []byte, err error) { func (t *transport) readPacket() (p []byte, err error) {
for { for {
p, err = t.reader.readPacket(t.bufReader) p, err = t.reader.readPacket(t.bufReader, t.strictMode)
if err != nil { if err != nil {
break break
} }
if len(p) == 0 || (p[0] != msgIgnore && p[0] != msgDebug) { // in strict mode we pass through DEBUG and IGNORE packets only during the initial KEX
if len(p) == 0 || (t.strictMode && !t.initialKEXDone) || (p[0] != msgIgnore && p[0] != msgDebug) {
break break
} }
} }
@ -127,7 +143,7 @@ func (t *transport) readPacket() (p []byte, err error) {
return p, err return p, err
} }
func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) { func (s *connectionState) readPacket(r *bufio.Reader, strictMode bool) ([]byte, error) {
packet, err := s.packetCipher.readCipherPacket(s.seqNum, r) packet, err := s.packetCipher.readCipherPacket(s.seqNum, r)
s.seqNum++ s.seqNum++
if err == nil && len(packet) == 0 { if err == nil && len(packet) == 0 {
@ -140,6 +156,9 @@ func (s *connectionState) readPacket(r *bufio.Reader) ([]byte, error) {
select { select {
case cipher := <-s.pendingKeyChange: case cipher := <-s.pendingKeyChange:
s.packetCipher = cipher s.packetCipher = cipher
if strictMode {
s.seqNum = 0
}
default: default:
return nil, errors.New("ssh: got bogus newkeys message") return nil, errors.New("ssh: got bogus newkeys message")
} }
@ -170,10 +189,10 @@ func (t *transport) writePacket(packet []byte) error {
if debugTransport { if debugTransport {
t.printPacket(packet, true) t.printPacket(packet, true)
} }
return t.writer.writePacket(t.bufWriter, t.rand, packet) return t.writer.writePacket(t.bufWriter, t.rand, packet, t.strictMode)
} }
func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte) error { func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []byte, strictMode bool) error {
changeKeys := len(packet) > 0 && packet[0] == msgNewKeys changeKeys := len(packet) > 0 && packet[0] == msgNewKeys
err := s.packetCipher.writeCipherPacket(s.seqNum, w, rand, packet) err := s.packetCipher.writeCipherPacket(s.seqNum, w, rand, packet)
@ -188,6 +207,9 @@ func (s *connectionState) writePacket(w *bufio.Writer, rand io.Reader, packet []
select { select {
case cipher := <-s.pendingKeyChange: case cipher := <-s.pendingKeyChange:
s.packetCipher = cipher s.packetCipher = cipher
if strictMode {
s.seqNum = 0
}
default: default:
panic("ssh: no key material for msgNewKeys") panic("ssh: no key material for msgNewKeys")
} }

View File

@ -1510,13 +1510,12 @@ func (mh *MetaHeadersFrame) checkPseudos() error {
} }
func (fr *Framer) maxHeaderStringLen() int { func (fr *Framer) maxHeaderStringLen() int {
v := fr.maxHeaderListSize() v := int(fr.maxHeaderListSize())
if uint32(int(v)) == v { if v < 0 {
return int(v) // If maxHeaderListSize overflows an int, use no limit (0).
}
// They had a crazy big number for MaxHeaderBytes anyway,
// so give them unlimited header lengths:
return 0 return 0
}
return v
} }
// readMetaFrame returns 0 or more CONTINUATION frames from fr and // readMetaFrame returns 0 or more CONTINUATION frames from fr and

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9 //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
package unix package unix

View File

@ -248,6 +248,7 @@ struct ltchars {
#include <linux/module.h> #include <linux/module.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/net_namespace.h> #include <linux/net_namespace.h>
#include <linux/nfc.h> #include <linux/nfc.h>
@ -283,10 +284,6 @@ struct ltchars {
#include <asm/termbits.h> #include <asm/termbits.h>
#endif #endif
#ifndef MSG_FASTOPEN
#define MSG_FASTOPEN 0x20000000
#endif
#ifndef PTRACE_GETREGS #ifndef PTRACE_GETREGS
#define PTRACE_GETREGS 0xc #define PTRACE_GETREGS 0xc
#endif #endif
@ -295,14 +292,6 @@ struct ltchars {
#define PTRACE_SETREGS 0xd #define PTRACE_SETREGS 0xd
#endif #endif
#ifndef SOL_NETLINK
#define SOL_NETLINK 270
#endif
#ifndef SOL_SMC
#define SOL_SMC 286
#endif
#ifdef SOL_BLUETOOTH #ifdef SOL_BLUETOOTH
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h // SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
// but it is already in bluetooth_linux.go // but it is already in bluetooth_linux.go
@ -319,10 +308,23 @@ struct ltchars {
#undef TIPC_WAIT_FOREVER #undef TIPC_WAIT_FOREVER
#define TIPC_WAIT_FOREVER 0xffffffff #define TIPC_WAIT_FOREVER 0xffffffff
// Copied from linux/l2tp.h // Copied from linux/netfilter/nf_nat.h
// Including linux/l2tp.h here causes conflicts between linux/in.h // Including linux/netfilter/nf_nat.h here causes conflicts between linux/in.h
// and netinet/in.h included via net/route.h above. // and netinet/in.h.
#define IPPROTO_L2TP 115 #define NF_NAT_RANGE_MAP_IPS (1 << 0)
#define NF_NAT_RANGE_PROTO_SPECIFIED (1 << 1)
#define NF_NAT_RANGE_PROTO_RANDOM (1 << 2)
#define NF_NAT_RANGE_PERSISTENT (1 << 3)
#define NF_NAT_RANGE_PROTO_RANDOM_FULLY (1 << 4)
#define NF_NAT_RANGE_PROTO_OFFSET (1 << 5)
#define NF_NAT_RANGE_NETMAP (1 << 6)
#define NF_NAT_RANGE_PROTO_RANDOM_ALL \
(NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
#define NF_NAT_RANGE_MASK \
(NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED | \
NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PERSISTENT | \
NF_NAT_RANGE_PROTO_RANDOM_FULLY | NF_NAT_RANGE_PROTO_OFFSET | \
NF_NAT_RANGE_NETMAP)
// Copied from linux/hid.h. // Copied from linux/hid.h.
// Keep in sync with the size of the referenced fields. // Keep in sync with the size of the referenced fields.
@ -582,7 +584,7 @@ ccflags="$@"
$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ || $2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
$2 ~ /^KEYCTL_/ || $2 ~ /^KEYCTL_/ ||
$2 ~ /^PERF_/ || $2 ~ /^PERF_/ ||
$2 ~ /^SECCOMP_MODE_/ || $2 ~ /^SECCOMP_/ ||
$2 ~ /^SEEK_/ || $2 ~ /^SEEK_/ ||
$2 ~ /^SCHED_/ || $2 ~ /^SCHED_/ ||
$2 ~ /^SPLICE_/ || $2 ~ /^SPLICE_/ ||
@ -603,6 +605,9 @@ ccflags="$@"
$2 ~ /^FSOPT_/ || $2 ~ /^FSOPT_/ ||
$2 ~ /^WDIO[CFS]_/ || $2 ~ /^WDIO[CFS]_/ ||
$2 ~ /^NFN/ || $2 ~ /^NFN/ ||
$2 !~ /^NFT_META_IIFTYPE/ &&
$2 ~ /^NFT_/ ||
$2 ~ /^NF_NAT_/ ||
$2 ~ /^XDP_/ || $2 ~ /^XDP_/ ||
$2 ~ /^RWF_/ || $2 ~ /^RWF_/ ||
$2 ~ /^(HDIO|WIN|SMART)_/ || $2 ~ /^(HDIO|WIN|SMART)_/ ||

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build darwin && go1.12 //go:build darwin
package unix package unix

View File

@ -13,6 +13,7 @@
package unix package unix
import ( import (
"errors"
"sync" "sync"
"unsafe" "unsafe"
) )
@ -169,25 +170,26 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
func Uname(uname *Utsname) error { func Uname(uname *Utsname) error {
mib := []_C_int{CTL_KERN, KERN_OSTYPE} mib := []_C_int{CTL_KERN, KERN_OSTYPE}
n := unsafe.Sizeof(uname.Sysname) n := unsafe.Sizeof(uname.Sysname)
if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil { // Suppress ENOMEM errors to be compatible with the C library __xuname() implementation.
if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
return err return err
} }
mib = []_C_int{CTL_KERN, KERN_HOSTNAME} mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
n = unsafe.Sizeof(uname.Nodename) n = unsafe.Sizeof(uname.Nodename)
if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil { if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
return err return err
} }
mib = []_C_int{CTL_KERN, KERN_OSRELEASE} mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
n = unsafe.Sizeof(uname.Release) n = unsafe.Sizeof(uname.Release)
if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil { if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
return err return err
} }
mib = []_C_int{CTL_KERN, KERN_VERSION} mib = []_C_int{CTL_KERN, KERN_VERSION}
n = unsafe.Sizeof(uname.Version) n = unsafe.Sizeof(uname.Version)
if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil { if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
return err return err
} }
@ -205,7 +207,7 @@ func Uname(uname *Utsname) error {
mib = []_C_int{CTL_HW, HW_MACHINE} mib = []_C_int{CTL_HW, HW_MACHINE}
n = unsafe.Sizeof(uname.Machine) n = unsafe.Sizeof(uname.Machine)
if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil { if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
return err return err
} }

View File

@ -1849,6 +1849,105 @@ func Dup2(oldfd, newfd int) error {
//sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error) //sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error)
//sys Fsopen(fsName string, flags int) (fd int, err error) //sys Fsopen(fsName string, flags int) (fd int, err error)
//sys Fspick(dirfd int, pathName string, flags int) (fd int, err error) //sys Fspick(dirfd int, pathName string, flags int) (fd int, err error)
//sys fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error)
func fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) {
var keyp *byte
if keyp, err = BytePtrFromString(key); err != nil {
return
}
return fsconfig(fd, cmd, keyp, value, aux)
}
// FsconfigSetFlag is equivalent to fsconfig(2) called
// with cmd == FSCONFIG_SET_FLAG.
//
// fd is the filesystem context to act upon.
// key the parameter key to set.
func FsconfigSetFlag(fd int, key string) (err error) {
return fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0)
}
// FsconfigSetString is equivalent to fsconfig(2) called
// with cmd == FSCONFIG_SET_STRING.
//
// fd is the filesystem context to act upon.
// key the parameter key to set.
// value is the parameter value to set.
func FsconfigSetString(fd int, key string, value string) (err error) {
var valuep *byte
if valuep, err = BytePtrFromString(value); err != nil {
return
}
return fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0)
}
// FsconfigSetBinary is equivalent to fsconfig(2) called
// with cmd == FSCONFIG_SET_BINARY.
//
// fd is the filesystem context to act upon.
// key the parameter key to set.
// value is the parameter value to set.
func FsconfigSetBinary(fd int, key string, value []byte) (err error) {
if len(value) == 0 {
return EINVAL
}
return fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value))
}
// FsconfigSetPath is equivalent to fsconfig(2) called
// with cmd == FSCONFIG_SET_PATH.
//
// fd is the filesystem context to act upon.
// key the parameter key to set.
// path is a non-empty path for specified key.
// atfd is a file descriptor at which to start lookup from or AT_FDCWD.
func FsconfigSetPath(fd int, key string, path string, atfd int) (err error) {
var valuep *byte
if valuep, err = BytePtrFromString(path); err != nil {
return
}
return fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd)
}
// FsconfigSetPathEmpty is equivalent to fsconfig(2) called
// with cmd == FSCONFIG_SET_PATH_EMPTY. The same as
// FconfigSetPath but with AT_PATH_EMPTY implied.
func FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) {
var valuep *byte
if valuep, err = BytePtrFromString(path); err != nil {
return
}
return fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd)
}
// FsconfigSetFd is equivalent to fsconfig(2) called
// with cmd == FSCONFIG_SET_FD.
//
// fd is the filesystem context to act upon.
// key the parameter key to set.
// value is a file descriptor to be assigned to specified key.
func FsconfigSetFd(fd int, key string, value int) (err error) {
return fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value)
}
// FsconfigCreate is equivalent to fsconfig(2) called
// with cmd == FSCONFIG_CMD_CREATE.
//
// fd is the filesystem context to act upon.
func FsconfigCreate(fd int) (err error) {
return fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0)
}
// FsconfigReconfigure is equivalent to fsconfig(2) called
// with cmd == FSCONFIG_CMD_RECONFIGURE.
//
// fd is the filesystem context to act upon.
func FsconfigReconfigure(fd int) (err error) {
return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0)
}
//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
//sysnb Getpgid(pid int) (pgid int, err error) //sysnb Getpgid(pid int) (pgid int, err error)

View File

@ -1785,6 +1785,8 @@ const (
LANDLOCK_ACCESS_FS_REMOVE_FILE = 0x20 LANDLOCK_ACCESS_FS_REMOVE_FILE = 0x20
LANDLOCK_ACCESS_FS_TRUNCATE = 0x4000 LANDLOCK_ACCESS_FS_TRUNCATE = 0x4000
LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2 LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2
LANDLOCK_ACCESS_NET_BIND_TCP = 0x1
LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2
LANDLOCK_CREATE_RULESET_VERSION = 0x1 LANDLOCK_CREATE_RULESET_VERSION = 0x1
LINUX_REBOOT_CMD_CAD_OFF = 0x0 LINUX_REBOOT_CMD_CAD_OFF = 0x0
LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef
@ -2127,6 +2129,60 @@ const (
NFNL_SUBSYS_QUEUE = 0x3 NFNL_SUBSYS_QUEUE = 0x3
NFNL_SUBSYS_ULOG = 0x4 NFNL_SUBSYS_ULOG = 0x4
NFS_SUPER_MAGIC = 0x6969 NFS_SUPER_MAGIC = 0x6969
NFT_CHAIN_FLAGS = 0x7
NFT_CHAIN_MAXNAMELEN = 0x100
NFT_CT_MAX = 0x17
NFT_DATA_RESERVED_MASK = 0xffffff00
NFT_DATA_VALUE_MAXLEN = 0x40
NFT_EXTHDR_OP_MAX = 0x4
NFT_FIB_RESULT_MAX = 0x3
NFT_INNER_MASK = 0xf
NFT_LOGLEVEL_MAX = 0x8
NFT_NAME_MAXLEN = 0x100
NFT_NG_MAX = 0x1
NFT_OBJECT_CONNLIMIT = 0x5
NFT_OBJECT_COUNTER = 0x1
NFT_OBJECT_CT_EXPECT = 0x9
NFT_OBJECT_CT_HELPER = 0x3
NFT_OBJECT_CT_TIMEOUT = 0x7
NFT_OBJECT_LIMIT = 0x4
NFT_OBJECT_MAX = 0xa
NFT_OBJECT_QUOTA = 0x2
NFT_OBJECT_SECMARK = 0x8
NFT_OBJECT_SYNPROXY = 0xa
NFT_OBJECT_TUNNEL = 0x6
NFT_OBJECT_UNSPEC = 0x0
NFT_OBJ_MAXNAMELEN = 0x100
NFT_OSF_MAXGENRELEN = 0x10
NFT_QUEUE_FLAG_BYPASS = 0x1
NFT_QUEUE_FLAG_CPU_FANOUT = 0x2
NFT_QUEUE_FLAG_MASK = 0x3
NFT_REG32_COUNT = 0x10
NFT_REG32_SIZE = 0x4
NFT_REG_MAX = 0x4
NFT_REG_SIZE = 0x10
NFT_REJECT_ICMPX_MAX = 0x3
NFT_RT_MAX = 0x4
NFT_SECMARK_CTX_MAXLEN = 0x100
NFT_SET_MAXNAMELEN = 0x100
NFT_SOCKET_MAX = 0x3
NFT_TABLE_F_MASK = 0x3
NFT_TABLE_MAXNAMELEN = 0x100
NFT_TRACETYPE_MAX = 0x3
NFT_TUNNEL_F_MASK = 0x7
NFT_TUNNEL_MAX = 0x1
NFT_TUNNEL_MODE_MAX = 0x2
NFT_USERDATA_MAXLEN = 0x100
NFT_XFRM_KEY_MAX = 0x6
NF_NAT_RANGE_MAP_IPS = 0x1
NF_NAT_RANGE_MASK = 0x7f
NF_NAT_RANGE_NETMAP = 0x40
NF_NAT_RANGE_PERSISTENT = 0x8
NF_NAT_RANGE_PROTO_OFFSET = 0x20
NF_NAT_RANGE_PROTO_RANDOM = 0x4
NF_NAT_RANGE_PROTO_RANDOM_ALL = 0x14
NF_NAT_RANGE_PROTO_RANDOM_FULLY = 0x10
NF_NAT_RANGE_PROTO_SPECIFIED = 0x2
NILFS_SUPER_MAGIC = 0x3434 NILFS_SUPER_MAGIC = 0x3434
NL0 = 0x0 NL0 = 0x0
NL1 = 0x100 NL1 = 0x100
@ -2411,6 +2467,7 @@ const (
PR_MCE_KILL_GET = 0x22 PR_MCE_KILL_GET = 0x22
PR_MCE_KILL_LATE = 0x0 PR_MCE_KILL_LATE = 0x0
PR_MCE_KILL_SET = 0x1 PR_MCE_KILL_SET = 0x1
PR_MDWE_NO_INHERIT = 0x2
PR_MDWE_REFUSE_EXEC_GAIN = 0x1 PR_MDWE_REFUSE_EXEC_GAIN = 0x1
PR_MPX_DISABLE_MANAGEMENT = 0x2c PR_MPX_DISABLE_MANAGEMENT = 0x2c
PR_MPX_ENABLE_MANAGEMENT = 0x2b PR_MPX_ENABLE_MANAGEMENT = 0x2b
@ -2615,8 +2672,9 @@ const (
RTAX_FEATURES = 0xc RTAX_FEATURES = 0xc
RTAX_FEATURE_ALLFRAG = 0x8 RTAX_FEATURE_ALLFRAG = 0x8
RTAX_FEATURE_ECN = 0x1 RTAX_FEATURE_ECN = 0x1
RTAX_FEATURE_MASK = 0xf RTAX_FEATURE_MASK = 0x1f
RTAX_FEATURE_SACK = 0x2 RTAX_FEATURE_SACK = 0x2
RTAX_FEATURE_TCP_USEC_TS = 0x10
RTAX_FEATURE_TIMESTAMP = 0x4 RTAX_FEATURE_TIMESTAMP = 0x4
RTAX_HOPLIMIT = 0xa RTAX_HOPLIMIT = 0xa
RTAX_INITCWND = 0xb RTAX_INITCWND = 0xb
@ -2859,9 +2917,38 @@ const (
SCM_RIGHTS = 0x1 SCM_RIGHTS = 0x1
SCM_TIMESTAMP = 0x1d SCM_TIMESTAMP = 0x1d
SC_LOG_FLUSH = 0x100000 SC_LOG_FLUSH = 0x100000
SECCOMP_ADDFD_FLAG_SEND = 0x2
SECCOMP_ADDFD_FLAG_SETFD = 0x1
SECCOMP_FILTER_FLAG_LOG = 0x2
SECCOMP_FILTER_FLAG_NEW_LISTENER = 0x8
SECCOMP_FILTER_FLAG_SPEC_ALLOW = 0x4
SECCOMP_FILTER_FLAG_TSYNC = 0x1
SECCOMP_FILTER_FLAG_TSYNC_ESRCH = 0x10
SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV = 0x20
SECCOMP_GET_ACTION_AVAIL = 0x2
SECCOMP_GET_NOTIF_SIZES = 0x3
SECCOMP_IOCTL_NOTIF_RECV = 0xc0502100
SECCOMP_IOCTL_NOTIF_SEND = 0xc0182101
SECCOMP_IOC_MAGIC = '!'
SECCOMP_MODE_DISABLED = 0x0 SECCOMP_MODE_DISABLED = 0x0
SECCOMP_MODE_FILTER = 0x2 SECCOMP_MODE_FILTER = 0x2
SECCOMP_MODE_STRICT = 0x1 SECCOMP_MODE_STRICT = 0x1
SECCOMP_RET_ACTION = 0x7fff0000
SECCOMP_RET_ACTION_FULL = 0xffff0000
SECCOMP_RET_ALLOW = 0x7fff0000
SECCOMP_RET_DATA = 0xffff
SECCOMP_RET_ERRNO = 0x50000
SECCOMP_RET_KILL = 0x0
SECCOMP_RET_KILL_PROCESS = 0x80000000
SECCOMP_RET_KILL_THREAD = 0x0
SECCOMP_RET_LOG = 0x7ffc0000
SECCOMP_RET_TRACE = 0x7ff00000
SECCOMP_RET_TRAP = 0x30000
SECCOMP_RET_USER_NOTIF = 0x7fc00000
SECCOMP_SET_MODE_FILTER = 0x1
SECCOMP_SET_MODE_STRICT = 0x0
SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP = 0x1
SECCOMP_USER_NOTIF_FLAG_CONTINUE = 0x1
SECRETMEM_MAGIC = 0x5345434d SECRETMEM_MAGIC = 0x5345434d
SECURITYFS_MAGIC = 0x73636673 SECURITYFS_MAGIC = 0x73636673
SEEK_CUR = 0x1 SEEK_CUR = 0x1
@ -3021,6 +3108,7 @@ const (
SOL_TIPC = 0x10f SOL_TIPC = 0x10f
SOL_TLS = 0x11a SOL_TLS = 0x11a
SOL_UDP = 0x11 SOL_UDP = 0x11
SOL_VSOCK = 0x11f
SOL_X25 = 0x106 SOL_X25 = 0x106
SOL_XDP = 0x11b SOL_XDP = 0x11b
SOMAXCONN = 0x1000 SOMAXCONN = 0x1000

View File

@ -281,6 +281,9 @@ const (
SCM_TIMESTAMPNS = 0x23 SCM_TIMESTAMPNS = 0x23
SCM_TXTIME = 0x3d SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29 SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
SFD_CLOEXEC = 0x80000 SFD_CLOEXEC = 0x80000
SFD_NONBLOCK = 0x800 SFD_NONBLOCK = 0x800
SIOCATMARK = 0x8905 SIOCATMARK = 0x8905

View File

@ -282,6 +282,9 @@ const (
SCM_TIMESTAMPNS = 0x23 SCM_TIMESTAMPNS = 0x23
SCM_TXTIME = 0x3d SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29 SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
SFD_CLOEXEC = 0x80000 SFD_CLOEXEC = 0x80000
SFD_NONBLOCK = 0x800 SFD_NONBLOCK = 0x800
SIOCATMARK = 0x8905 SIOCATMARK = 0x8905

View File

@ -288,6 +288,9 @@ const (
SCM_TIMESTAMPNS = 0x23 SCM_TIMESTAMPNS = 0x23
SCM_TXTIME = 0x3d SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29 SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
SFD_CLOEXEC = 0x80000 SFD_CLOEXEC = 0x80000
SFD_NONBLOCK = 0x800 SFD_NONBLOCK = 0x800
SIOCATMARK = 0x8905 SIOCATMARK = 0x8905

View File

@ -278,6 +278,9 @@ const (
SCM_TIMESTAMPNS = 0x23 SCM_TIMESTAMPNS = 0x23
SCM_TXTIME = 0x3d SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29 SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
SFD_CLOEXEC = 0x80000 SFD_CLOEXEC = 0x80000
SFD_NONBLOCK = 0x800 SFD_NONBLOCK = 0x800
SIOCATMARK = 0x8905 SIOCATMARK = 0x8905

View File

@ -275,6 +275,9 @@ const (
SCM_TIMESTAMPNS = 0x23 SCM_TIMESTAMPNS = 0x23
SCM_TXTIME = 0x3d SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29 SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
SFD_CLOEXEC = 0x80000 SFD_CLOEXEC = 0x80000
SFD_NONBLOCK = 0x800 SFD_NONBLOCK = 0x800
SIOCATMARK = 0x8905 SIOCATMARK = 0x8905

View File

@ -281,6 +281,9 @@ const (
SCM_TIMESTAMPNS = 0x23 SCM_TIMESTAMPNS = 0x23
SCM_TXTIME = 0x3d SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29 SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
SFD_CLOEXEC = 0x80000 SFD_CLOEXEC = 0x80000
SFD_NONBLOCK = 0x80 SFD_NONBLOCK = 0x80
SIOCATMARK = 0x40047307 SIOCATMARK = 0x40047307

View File

@ -281,6 +281,9 @@ const (
SCM_TIMESTAMPNS = 0x23 SCM_TIMESTAMPNS = 0x23
SCM_TXTIME = 0x3d SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29 SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
SFD_CLOEXEC = 0x80000 SFD_CLOEXEC = 0x80000
SFD_NONBLOCK = 0x80 SFD_NONBLOCK = 0x80
SIOCATMARK = 0x40047307 SIOCATMARK = 0x40047307

View File

@ -281,6 +281,9 @@ const (
SCM_TIMESTAMPNS = 0x23 SCM_TIMESTAMPNS = 0x23
SCM_TXTIME = 0x3d SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29 SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
SFD_CLOEXEC = 0x80000 SFD_CLOEXEC = 0x80000
SFD_NONBLOCK = 0x80 SFD_NONBLOCK = 0x80
SIOCATMARK = 0x40047307 SIOCATMARK = 0x40047307

View File

@ -281,6 +281,9 @@ const (
SCM_TIMESTAMPNS = 0x23 SCM_TIMESTAMPNS = 0x23
SCM_TXTIME = 0x3d SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29 SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
SFD_CLOEXEC = 0x80000 SFD_CLOEXEC = 0x80000
SFD_NONBLOCK = 0x80 SFD_NONBLOCK = 0x80
SIOCATMARK = 0x40047307 SIOCATMARK = 0x40047307

View File

@ -336,6 +336,9 @@ const (
SCM_TIMESTAMPNS = 0x23 SCM_TIMESTAMPNS = 0x23
SCM_TXTIME = 0x3d SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29 SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
SFD_CLOEXEC = 0x80000 SFD_CLOEXEC = 0x80000
SFD_NONBLOCK = 0x800 SFD_NONBLOCK = 0x800
SIOCATMARK = 0x8905 SIOCATMARK = 0x8905

View File

@ -340,6 +340,9 @@ const (
SCM_TIMESTAMPNS = 0x23 SCM_TIMESTAMPNS = 0x23
SCM_TXTIME = 0x3d SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29 SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
SFD_CLOEXEC = 0x80000 SFD_CLOEXEC = 0x80000
SFD_NONBLOCK = 0x800 SFD_NONBLOCK = 0x800
SIOCATMARK = 0x8905 SIOCATMARK = 0x8905

View File

@ -340,6 +340,9 @@ const (
SCM_TIMESTAMPNS = 0x23 SCM_TIMESTAMPNS = 0x23
SCM_TXTIME = 0x3d SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29 SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
SFD_CLOEXEC = 0x80000 SFD_CLOEXEC = 0x80000
SFD_NONBLOCK = 0x800 SFD_NONBLOCK = 0x800
SIOCATMARK = 0x8905 SIOCATMARK = 0x8905

View File

@ -272,6 +272,9 @@ const (
SCM_TIMESTAMPNS = 0x23 SCM_TIMESTAMPNS = 0x23
SCM_TXTIME = 0x3d SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29 SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
SFD_CLOEXEC = 0x80000 SFD_CLOEXEC = 0x80000
SFD_NONBLOCK = 0x800 SFD_NONBLOCK = 0x800
SIOCATMARK = 0x8905 SIOCATMARK = 0x8905

View File

@ -344,6 +344,9 @@ const (
SCM_TIMESTAMPNS = 0x23 SCM_TIMESTAMPNS = 0x23
SCM_TXTIME = 0x3d SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29 SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
SFD_CLOEXEC = 0x80000 SFD_CLOEXEC = 0x80000
SFD_NONBLOCK = 0x800 SFD_NONBLOCK = 0x800
SIOCATMARK = 0x8905 SIOCATMARK = 0x8905

View File

@ -335,6 +335,9 @@ const (
SCM_TIMESTAMPNS = 0x21 SCM_TIMESTAMPNS = 0x21
SCM_TXTIME = 0x3f SCM_TXTIME = 0x3f
SCM_WIFI_STATUS = 0x25 SCM_WIFI_STATUS = 0x25
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
SFD_CLOEXEC = 0x400000 SFD_CLOEXEC = 0x400000
SFD_NONBLOCK = 0x4000 SFD_NONBLOCK = 0x4000
SF_FP = 0x38 SF_FP = 0x38

View File

@ -906,6 +906,16 @@ func Fspick(dirfd int, pathName string, flags int) (fd int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) {
_, _, e1 := Syscall6(SYS_FSCONFIG, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(value)), uintptr(aux), 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func Getdents(fd int, buf []byte) (n int, err error) { func Getdents(fd int, buf []byte) (n int, err error) {
var _p0 unsafe.Pointer var _p0 unsafe.Pointer
if len(buf) > 0 { if len(buf) > 0 {

View File

@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) {
var libc_unveil_trampoline_addr uintptr var libc_unveil_trampoline_addr uintptr
//go:cgo_import_dynamic libc_unveil unveil "libc.so" //go:cgo_import_dynamic libc_unveil unveil "libc.so"

View File

@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) {
var libc_unveil_trampoline_addr uintptr var libc_unveil_trampoline_addr uintptr
//go:cgo_import_dynamic libc_unveil unveil "libc.so" //go:cgo_import_dynamic libc_unveil unveil "libc.so"

View File

@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) {
var libc_unveil_trampoline_addr uintptr var libc_unveil_trampoline_addr uintptr
//go:cgo_import_dynamic libc_unveil unveil "libc.so" //go:cgo_import_dynamic libc_unveil unveil "libc.so"

View File

@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) {
var libc_unveil_trampoline_addr uintptr var libc_unveil_trampoline_addr uintptr
//go:cgo_import_dynamic libc_unveil unveil "libc.so" //go:cgo_import_dynamic libc_unveil unveil "libc.so"

View File

@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) {
var libc_unveil_trampoline_addr uintptr var libc_unveil_trampoline_addr uintptr
//go:cgo_import_dynamic libc_unveil unveil "libc.so" //go:cgo_import_dynamic libc_unveil unveil "libc.so"

View File

@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) {
var libc_unveil_trampoline_addr uintptr var libc_unveil_trampoline_addr uintptr
//go:cgo_import_dynamic libc_unveil unveil "libc.so" //go:cgo_import_dynamic libc_unveil unveil "libc.so"

View File

@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) {
var libc_unveil_trampoline_addr uintptr var libc_unveil_trampoline_addr uintptr
//go:cgo_import_dynamic libc_unveil unveil "libc.so" //go:cgo_import_dynamic libc_unveil unveil "libc.so"

View File

@ -448,4 +448,8 @@ const (
SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_SET_MEMPOLICY_HOME_NODE = 450
SYS_CACHESTAT = 451 SYS_CACHESTAT = 451
SYS_FCHMODAT2 = 452 SYS_FCHMODAT2 = 452
SYS_MAP_SHADOW_STACK = 453
SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456
) )

View File

@ -371,4 +371,7 @@ const (
SYS_CACHESTAT = 451 SYS_CACHESTAT = 451
SYS_FCHMODAT2 = 452 SYS_FCHMODAT2 = 452
SYS_MAP_SHADOW_STACK = 453 SYS_MAP_SHADOW_STACK = 453
SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456
) )

View File

@ -412,4 +412,8 @@ const (
SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_SET_MEMPOLICY_HOME_NODE = 450
SYS_CACHESTAT = 451 SYS_CACHESTAT = 451
SYS_FCHMODAT2 = 452 SYS_FCHMODAT2 = 452
SYS_MAP_SHADOW_STACK = 453
SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456
) )

View File

@ -315,4 +315,8 @@ const (
SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_SET_MEMPOLICY_HOME_NODE = 450
SYS_CACHESTAT = 451 SYS_CACHESTAT = 451
SYS_FCHMODAT2 = 452 SYS_FCHMODAT2 = 452
SYS_MAP_SHADOW_STACK = 453
SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456
) )

View File

@ -309,4 +309,8 @@ const (
SYS_SET_MEMPOLICY_HOME_NODE = 450 SYS_SET_MEMPOLICY_HOME_NODE = 450
SYS_CACHESTAT = 451 SYS_CACHESTAT = 451
SYS_FCHMODAT2 = 452 SYS_FCHMODAT2 = 452
SYS_MAP_SHADOW_STACK = 453
SYS_FUTEX_WAKE = 454
SYS_FUTEX_WAIT = 455
SYS_FUTEX_REQUEUE = 456
) )

View File

@ -432,4 +432,8 @@ const (
SYS_SET_MEMPOLICY_HOME_NODE = 4450 SYS_SET_MEMPOLICY_HOME_NODE = 4450
SYS_CACHESTAT = 4451 SYS_CACHESTAT = 4451
SYS_FCHMODAT2 = 4452 SYS_FCHMODAT2 = 4452
SYS_MAP_SHADOW_STACK = 4453
SYS_FUTEX_WAKE = 4454
SYS_FUTEX_WAIT = 4455
SYS_FUTEX_REQUEUE = 4456
) )

View File

@ -362,4 +362,8 @@ const (
SYS_SET_MEMPOLICY_HOME_NODE = 5450 SYS_SET_MEMPOLICY_HOME_NODE = 5450
SYS_CACHESTAT = 5451 SYS_CACHESTAT = 5451
SYS_FCHMODAT2 = 5452 SYS_FCHMODAT2 = 5452
SYS_MAP_SHADOW_STACK = 5453
SYS_FUTEX_WAKE = 5454
SYS_FUTEX_WAIT = 5455
SYS_FUTEX_REQUEUE = 5456
) )

Some files were not shown because too many files have changed in this diff Show More