diff --git a/go.mod b/go.mod
index 5436658991..0115a24756 100644
--- a/go.mod
+++ b/go.mod
@@ -9,7 +9,7 @@ require (
 	github.com/Masterminds/semver/v3 v3.3.1
 	github.com/containers/common v0.61.0
 	github.com/containers/image/v5 v5.33.0
-	github.com/containers/ocicrypt v1.2.0
+	github.com/containers/ocicrypt v1.2.1
 	github.com/containers/storage v1.56.0
 	github.com/docker/distribution v2.8.3+incompatible
 	github.com/moby/sys/capability v0.4.0
@@ -109,6 +109,7 @@ require (
 	github.com/sigstore/rekor v1.3.6 // indirect
 	github.com/sigstore/sigstore v1.8.9 // indirect
 	github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
+	github.com/smallstep/pkcs7 v0.1.1 // indirect
 	github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 // indirect
 	github.com/sylabs/sif/v2 v2.19.1 // indirect
 	github.com/tchap/go-patricia/v2 v2.3.1 // indirect
@@ -120,20 +121,19 @@ require (
 	github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
 	github.com/xeipuuv/gojsonschema v1.2.0 // indirect
 	go.mongodb.org/mongo-driver v1.14.0 // indirect
-	go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect
 	go.opencensus.io v0.24.0 // indirect
 	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
 	go.opentelemetry.io/otel v1.28.0 // indirect
 	go.opentelemetry.io/otel/metric v1.28.0 // indirect
 	go.opentelemetry.io/otel/trace v1.28.0 // indirect
-	golang.org/x/crypto v0.29.0 // indirect
+	golang.org/x/crypto v0.30.0 // indirect
 	golang.org/x/mod v0.22.0 // indirect
 	golang.org/x/net v0.30.0 // indirect
 	golang.org/x/oauth2 v0.23.0 // indirect
-	golang.org/x/sync v0.9.0 // indirect
+	golang.org/x/sync v0.10.0 // indirect
 	golang.org/x/sys v0.28.0 // indirect
-	golang.org/x/text v0.20.0 // indirect
+	golang.org/x/text v0.21.0 // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
-	google.golang.org/grpc v1.67.0 // indirect
+	google.golang.org/grpc v1.68.1 // indirect
 	google.golang.org/protobuf v1.35.1 // indirect
 )
diff --git a/go.sum b/go.sum
index 4f03520abc..5a425a2ea0 100644
--- a/go.sum
+++ b/go.sum
@@ -47,8 +47,8 @@ github.com/containers/image/v5 v5.33.0 h1:6oPEFwTurf7pDTGw7TghqGs8K0+OvPtY/UyzU0
 github.com/containers/image/v5 v5.33.0/go.mod h1:T7HpASmvnp2H1u4cyckMvCzLuYgpD18dSmabSw0AcHk=
 github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
 github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
-github.com/containers/ocicrypt v1.2.0 h1:X14EgRK3xNFvJEfI5O4Qn4T3E25ANudSOZz/sirVuPM=
-github.com/containers/ocicrypt v1.2.0/go.mod h1:ZNviigQajtdlxIZGibvblVuIFBKIuUI2M0QM12SD31U=
+github.com/containers/ocicrypt v1.2.1 h1:0qIOTT9DoYwcKmxSt8QJt+VzMY18onl9jUXsxpVhSmM=
+github.com/containers/ocicrypt v1.2.1/go.mod h1:aD0AAqfMp0MtwqWgHM1bUwe1anx0VazI108CRrSKINQ=
 github.com/containers/storage v1.56.0 h1:DZ9KSkj6M2tvj/4bBoaJu3QDHRl35BwsZ4kmLJS97ZI=
 github.com/containers/storage v1.56.0/go.mod h1:c6WKowcAlED/DkWGNuL9bvGYqIWCVy7isRMdCSKWNjk=
 github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI=
@@ -299,6 +299,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ
 github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=
 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
+github.com/smallstep/pkcs7 v0.1.1 h1:x+rPdt2W088V9Vkjho4KtoggyktZJlMduZAtRHm68LU=
+github.com/smallstep/pkcs7 v0.1.1/go.mod h1:dL6j5AIz9GHjVEBTXtW+QliALcgM19RtXaTeyxI+AfA=
 github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
 github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
@@ -350,8 +352,6 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80=
 go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
-go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 h1:CCriYyAfq1Br1aIYettdHZTy8mBTIPo7We18TuO/bak=
-go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
 go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
 go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
@@ -376,9 +376,11 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
 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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
 golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
-golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
-golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
+golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
+golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
+golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
 golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak=
@@ -389,6 +391,9 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
 golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -404,6 +409,9 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
 golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
 golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -416,8 +424,11 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
-golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
+golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -429,14 +440,19 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
 golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
 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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
 golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
+golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
 golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
 golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -444,9 +460,11 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
-golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
+golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
 golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
 golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -459,6 +477,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
+golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
 golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o=
 golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -471,8 +491,8 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
 google.golang.org/genproto v0.0.0-20240823204242-4ba0660f739c h1:TYOEhrQMrNDTAd2rX9m+WgGr8Ku6YNuj1D7OX6rWSok=
-google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8=
-google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo=
+google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
+google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -480,8 +500,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
 google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
-google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
-google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
+google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0=
+google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
diff --git a/vendor/github.com/containers/ocicrypt/keywrap/pkcs7/keywrapper_pkcs7.go b/vendor/github.com/containers/ocicrypt/keywrap/pkcs7/keywrapper_pkcs7.go
index 603925dfea..7ca32fc802 100644
--- a/vendor/github.com/containers/ocicrypt/keywrap/pkcs7/keywrapper_pkcs7.go
+++ b/vendor/github.com/containers/ocicrypt/keywrap/pkcs7/keywrapper_pkcs7.go
@@ -25,7 +25,7 @@ import (
 	"github.com/containers/ocicrypt/config"
 	"github.com/containers/ocicrypt/keywrap"
 	"github.com/containers/ocicrypt/utils"
-	"go.mozilla.org/pkcs7"
+	"github.com/smallstep/pkcs7"
 )
 
 type pkcs7KeyWrapper struct {
diff --git a/vendor/go.mozilla.org/pkcs7/.gitignore b/vendor/github.com/smallstep/pkcs7/.gitignore
similarity index 88%
rename from vendor/go.mozilla.org/pkcs7/.gitignore
rename to vendor/github.com/smallstep/pkcs7/.gitignore
index daf913b1b3..948aae2acf 100644
--- a/vendor/go.mozilla.org/pkcs7/.gitignore
+++ b/vendor/github.com/smallstep/pkcs7/.gitignore
@@ -22,3 +22,7 @@ _testmain.go
 *.exe
 *.test
 *.prof
+
+# Development
+.envrc
+coverage.out
\ No newline at end of file
diff --git a/vendor/go.mozilla.org/pkcs7/LICENSE b/vendor/github.com/smallstep/pkcs7/LICENSE
similarity index 100%
rename from vendor/go.mozilla.org/pkcs7/LICENSE
rename to vendor/github.com/smallstep/pkcs7/LICENSE
diff --git a/vendor/go.mozilla.org/pkcs7/Makefile b/vendor/github.com/smallstep/pkcs7/Makefile
similarity index 100%
rename from vendor/go.mozilla.org/pkcs7/Makefile
rename to vendor/github.com/smallstep/pkcs7/Makefile
diff --git a/vendor/github.com/smallstep/pkcs7/README.md b/vendor/github.com/smallstep/pkcs7/README.md
new file mode 100644
index 0000000000..9d94e65f25
--- /dev/null
+++ b/vendor/github.com/smallstep/pkcs7/README.md
@@ -0,0 +1,63 @@
+# pkcs7
+
+[![Go Reference](https://pkg.go.dev/badge/github.com/smallstep/pkcs7.svg)](https://pkg.go.dev/github.com/smallstep/pkcs7)
+[![Build Status](https://github.com/smallstep/pkcs7/workflows/CI/badge.svg?query=branch%3Amain+event%3Apush)](https://github.com/smallstep/pkcs7/actions/workflows/ci.yml?query=branch%3Amain+event%3Apush)
+
+pkcs7 implements parsing and creating signed and enveloped messages.
+
+```go
+package main
+
+import (
+	"bytes"
+	"crypto/rsa"
+	"crypto/x509"
+	"encoding/pem"
+	"fmt"
+	"os"
+
+    "github.com/smallstep/pkcs7"
+)
+
+func SignAndDetach(content []byte, cert *x509.Certificate, privkey *rsa.PrivateKey) (signed []byte, err error) {
+	toBeSigned, err := NewSignedData(content)
+	if err != nil {
+		return fmt.Errorf("Cannot initialize signed data: %w", err)
+	}
+	if err = toBeSigned.AddSigner(cert, privkey, SignerInfoConfig{}); err != nil {
+		return fmt.Errorf("Cannot add signer: %w", err)
+	}
+
+	// Detach signature, omit if you want an embedded signature
+	toBeSigned.Detach()
+
+	signed, err = toBeSigned.Finish()
+	if err != nil {
+		return fmt.Errorf("Cannot finish signing data: %w", err)
+	}
+
+	// Verify the signature
+	pem.Encode(os.Stdout, &pem.Block{Type: "PKCS7", Bytes: signed})
+	p7, err := pkcs7.Parse(signed)
+	if err != nil {
+		return fmt.Errorf("Cannot parse our signed data: %w", err)
+	}
+
+	// since the signature was detached, reattach the content here
+	p7.Content = content
+
+	if bytes.Compare(content, p7.Content) != 0 {
+		return fmt.Errorf("Our content was not in the parsed data:\n\tExpected: %s\n\tActual: %s", content, p7.Content)
+	}
+	if err = p7.Verify(); err != nil {
+		return fmt.Errorf("Cannot verify our signed data: %w", err)
+	}
+
+	return signed, nil
+}
+```
+
+
+## Credits
+
+This is a fork of [mozilla-services/pkcs7](https://github.com/mozilla-services/pkcs7) which, itself, was a fork of [fullsailor/pkcs7](https://github.com/fullsailor/pkcs7).
diff --git a/vendor/go.mozilla.org/pkcs7/ber.go b/vendor/github.com/smallstep/pkcs7/ber.go
similarity index 91%
rename from vendor/go.mozilla.org/pkcs7/ber.go
rename to vendor/github.com/smallstep/pkcs7/ber.go
index 73da024a0d..52333215de 100644
--- a/vendor/go.mozilla.org/pkcs7/ber.go
+++ b/vendor/github.com/smallstep/pkcs7/ber.go
@@ -5,8 +5,6 @@ import (
 	"errors"
 )
 
-var encodeIndent = 0
-
 type asn1Object interface {
 	EncodeTo(writer *bytes.Buffer) error
 }
@@ -17,8 +15,6 @@ type asn1Structured struct {
 }
 
 func (s asn1Structured) EncodeTo(out *bytes.Buffer) error {
-	//fmt.Printf("%s--> tag: % X\n", strings.Repeat("| ", encodeIndent), s.tagBytes)
-	encodeIndent++
 	inner := new(bytes.Buffer)
 	for _, obj := range s.content {
 		err := obj.EncodeTo(inner)
@@ -26,7 +22,6 @@ func (s asn1Structured) EncodeTo(out *bytes.Buffer) error {
 			return err
 		}
 	}
-	encodeIndent--
 	out.Write(s.tagBytes)
 	encodeLength(out, inner.Len())
 	out.Write(inner.Bytes())
@@ -47,8 +42,8 @@ func (p asn1Primitive) EncodeTo(out *bytes.Buffer) error {
 	if err = encodeLength(out, p.length); err != nil {
 		return err
 	}
-	//fmt.Printf("%s--> tag: % X length: %d\n", strings.Repeat("| ", encodeIndent), p.tagBytes, p.length)
-	//fmt.Printf("%s--> content length: %d\n", strings.Repeat("| ", encodeIndent), len(p.content))
+	// fmt.Printf("%s--> tag: % X length: %d\n", strings.Repeat("| ", encodeIndent), p.tagBytes, p.length)
+	// fmt.Printf("%s--> content length: %d\n", strings.Repeat("| ", encodeIndent), len(p.content))
 	out.Write(p.content)
 
 	return nil
@@ -58,7 +53,7 @@ func ber2der(ber []byte) ([]byte, error) {
 	if len(ber) == 0 {
 		return nil, errors.New("ber2der: input ber is empty")
 	}
-	//fmt.Printf("--> ber2der: Transcoding %d bytes\n", len(ber))
+	// fmt.Printf("--> ber2der: Transcoding %d bytes\n", len(ber))
 	out := new(bytes.Buffer)
 
 	obj, _, err := readObject(ber, 0)
@@ -69,7 +64,7 @@ func ber2der(ber []byte) ([]byte, error) {
 
 	// if offset < len(ber) {
 	//	return nil, fmt.Errorf("ber2der: Content longer than expected. Got %d, expected %d", offset, len(ber))
-	//}
+	// }
 
 	return out.Bytes(), nil
 }
@@ -154,7 +149,7 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
 			}
 		}
 		// jvehent 20170227: this doesn't appear to be used anywhere...
-		//tag = tag*128 + ber[offset] - 0x80
+		// tag = tag*128 + ber[offset] - 0x80
 		offset++
 		if offset > berLen {
 			return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached")
@@ -204,7 +199,7 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
 	if length < 0 {
 		return nil, 0, errors.New("ber2der: invalid negative value found in BER tag length")
 	}
-	//fmt.Printf("--> length        : %d\n", length)
+	// fmt.Printf("--> length        : %d\n", length)
 	contentEnd := offset + length
 	if contentEnd > len(ber) {
 		return nil, 0, errors.New("ber2der: BER tag length is more than available data")
@@ -259,7 +254,7 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
 }
 
 func isIndefiniteTermination(ber []byte, offset int) (bool, error) {
-	if len(ber) - offset < 2 {
+	if len(ber)-offset < 2 {
 		return false, errors.New("ber2der: Invalid BER format")
 	}
 
@@ -267,5 +262,5 @@ func isIndefiniteTermination(ber []byte, offset int) (bool, error) {
 }
 
 func debugprint(format string, a ...interface{}) {
-	//fmt.Printf(format, a)
+	// fmt.Printf(format, a)
 }
diff --git a/vendor/go.mozilla.org/pkcs7/decrypt.go b/vendor/github.com/smallstep/pkcs7/decrypt.go
similarity index 62%
rename from vendor/go.mozilla.org/pkcs7/decrypt.go
rename to vendor/github.com/smallstep/pkcs7/decrypt.go
index 0d088d6287..76dc17f74c 100644
--- a/vendor/go.mozilla.org/pkcs7/decrypt.go
+++ b/vendor/github.com/smallstep/pkcs7/decrypt.go
@@ -9,6 +9,7 @@ import (
 	"crypto/rand"
 	"crypto/rsa"
 	"crypto/x509"
+	"crypto/x509/pkix"
 	"encoding/asn1"
 	"errors"
 	"fmt"
@@ -17,6 +18,12 @@ import (
 // ErrUnsupportedAlgorithm tells you when our quick dev assumptions have failed
 var ErrUnsupportedAlgorithm = errors.New("pkcs7: cannot decrypt data: only RSA, DES, DES-EDE3, AES-256-CBC and AES-128-GCM supported")
 
+// ErrUnsupportedAsymmetricEncryptionAlgorithm is returned when attempting to use an unknown asymmetric encryption algorithm
+var ErrUnsupportedAsymmetricEncryptionAlgorithm = errors.New("pkcs7: cannot decrypt data: only RSA PKCS#1 v1.5 and RSA OAEP are supported")
+
+// ErrUnsupportedKeyType is returned when attempting to encrypting keys using a key that's not an RSA key
+var ErrUnsupportedKeyType = errors.New("pkcs7: only RSA keys are supported")
+
 // ErrNotEncryptedContent is returned when attempting to Decrypt data that is not encrypted data
 var ErrNotEncryptedContent = errors.New("pkcs7: content data is a decryptable data type")
 
@@ -31,9 +38,21 @@ func (p7 *PKCS7) Decrypt(cert *x509.Certificate, pkey crypto.PrivateKey) ([]byte
 		return nil, errors.New("pkcs7: no enveloped recipient for provided certificate")
 	}
 	switch pkey := pkey.(type) {
-	case *rsa.PrivateKey:
-		var contentKey []byte
-		contentKey, err := rsa.DecryptPKCS1v15(rand.Reader, pkey, recipient.EncryptedKey)
+	case crypto.Decrypter:
+		var opts crypto.DecrypterOpts
+		switch algorithm := recipient.KeyEncryptionAlgorithm.Algorithm; {
+		case algorithm.Equal(OIDEncryptionAlgorithmRSAESOAEP):
+			hashFunc, err := getHashFuncForKeyEncryptionAlgorithm(recipient.KeyEncryptionAlgorithm)
+			if err != nil {
+				return nil, err
+			}
+			opts = &rsa.OAEPOptions{Hash: hashFunc}
+		case algorithm.Equal(OIDEncryptionAlgorithmRSA):
+			opts = &rsa.PKCS1v15DecryptOptions{}
+		default:
+			return nil, ErrUnsupportedAsymmetricEncryptionAlgorithm
+		}
+		contentKey, err := pkey.Decrypt(rand.Reader, recipient.EncryptedKey, opts)
 		if err != nil {
 			return nil, err
 		}
@@ -42,6 +61,44 @@ func (p7 *PKCS7) Decrypt(cert *x509.Certificate, pkey crypto.PrivateKey) ([]byte
 	return nil, ErrUnsupportedAlgorithm
 }
 
+// RFC 4055, 4.1
+// The current ASN.1 parser does not support non-integer defaults so the 'default:' tags here do nothing.
+type rsaOAEPAlgorithmParameters struct {
+	HashFunc    pkix.AlgorithmIdentifier `asn1:"optional,explicit,tag:0,default:sha1Identifier"`
+	MaskGenFunc pkix.AlgorithmIdentifier `asn1:"optional,explicit,tag:1,default:mgf1SHA1Identifier"`
+	PSourceFunc pkix.AlgorithmIdentifier `asn1:"optional,explicit,tag:2,default:pSpecifiedEmptyIdentifier"`
+}
+
+func getHashFuncForKeyEncryptionAlgorithm(keyEncryptionAlgorithm pkix.AlgorithmIdentifier) (crypto.Hash, error) {
+	invalidHashFunc := crypto.Hash(0)
+	params := &rsaOAEPAlgorithmParameters{
+		HashFunc: pkix.AlgorithmIdentifier{Algorithm: OIDDigestAlgorithmSHA1}, // set default hash algorithm to SHA1
+	}
+	var rest []byte
+	rest, err := asn1.Unmarshal(keyEncryptionAlgorithm.Parameters.FullBytes, params)
+	if err != nil {
+		return invalidHashFunc, fmt.Errorf("pkcs7: failed unmarshaling key encryption algorithm parameters: %v", err)
+	}
+	if len(rest) != 0 {
+		return invalidHashFunc, errors.New("pkcs7: trailing data after RSA OAEP parameters")
+	}
+
+	switch {
+	case params.HashFunc.Algorithm.Equal(OIDDigestAlgorithmSHA1):
+		return crypto.SHA1, nil
+	case params.HashFunc.Algorithm.Equal(OIDDigestAlgorithmSHA224):
+		return crypto.SHA224, nil
+	case params.HashFunc.Algorithm.Equal(OIDDigestAlgorithmSHA256):
+		return crypto.SHA256, nil
+	case params.HashFunc.Algorithm.Equal(OIDDigestAlgorithmSHA384):
+		return crypto.SHA384, nil
+	case params.HashFunc.Algorithm.Equal(OIDDigestAlgorithmSHA512):
+		return crypto.SHA512, nil
+	default:
+		return invalidHashFunc, errors.New("pkcs7: unsupported hash function for RSA OAEP")
+	}
+}
+
 // DecryptUsingPSK decrypts encrypted data using caller provided
 // pre-shared secret
 func (p7 *PKCS7) DecryptUsingPSK(key []byte) ([]byte, error) {
@@ -60,7 +117,6 @@ func (eci encryptedContentInfo) decrypt(key []byte) ([]byte, error) {
 		!alg.Equal(OIDEncryptionAlgorithmAES128CBC) &&
 		!alg.Equal(OIDEncryptionAlgorithmAES128GCM) &&
 		!alg.Equal(OIDEncryptionAlgorithmAES256GCM) {
-		fmt.Printf("Unsupported Content Encryption Algorithm: %s\n", alg)
 		return nil, ErrUnsupportedAlgorithm
 	}
 
@@ -147,10 +203,10 @@ func (eci encryptedContentInfo) decrypt(key []byte) ([]byte, error) {
 
 func unpad(data []byte, blocklen int) ([]byte, error) {
 	if blocklen < 1 {
-		return nil, fmt.Errorf("invalid blocklen %d", blocklen)
+		return nil, fmt.Errorf("pkcs7: invalid blocklen %d", blocklen)
 	}
 	if len(data)%blocklen != 0 || len(data) == 0 {
-		return nil, fmt.Errorf("invalid data len %d", len(data))
+		return nil, fmt.Errorf("pkcs7: invalid data len %d", len(data))
 	}
 
 	// the last byte is the length of padding
@@ -160,7 +216,7 @@ func unpad(data []byte, blocklen int) ([]byte, error) {
 	pad := data[len(data)-padlen:]
 	for _, padbyte := range pad {
 		if padbyte != byte(padlen) {
-			return nil, errors.New("invalid padding")
+			return nil, errors.New("pkcs7: invalid padding")
 		}
 	}
 
diff --git a/vendor/go.mozilla.org/pkcs7/encrypt.go b/vendor/github.com/smallstep/pkcs7/encrypt.go
similarity index 74%
rename from vendor/go.mozilla.org/pkcs7/encrypt.go
rename to vendor/github.com/smallstep/pkcs7/encrypt.go
index 6b2655708c..a5c96e7553 100644
--- a/vendor/go.mozilla.org/pkcs7/encrypt.go
+++ b/vendor/github.com/smallstep/pkcs7/encrypt.go
@@ -2,6 +2,7 @@ package pkcs7
 
 import (
 	"bytes"
+	"crypto"
 	"crypto/aes"
 	"crypto/cipher"
 	"crypto/des"
@@ -66,6 +67,24 @@ var ContentEncryptionAlgorithm = EncryptionAlgorithmDESCBC
 // content with an unsupported algorithm.
 var ErrUnsupportedEncryptionAlgorithm = errors.New("pkcs7: cannot encrypt content: only DES-CBC, AES-CBC, and AES-GCM supported")
 
+// KeyEncryptionAlgorithm determines the algorithm used to encrypt a
+// content key. Change the value of this variable to change which
+// algorithm is used in the Encrypt() function.
+var KeyEncryptionAlgorithm = OIDEncryptionAlgorithmRSA
+
+// ErrUnsupportedKeyEncryptionAlgorithm is returned when an
+// unsupported key encryption algorithm OID is provided.
+var ErrUnsupportedKeyEncryptionAlgorithm = errors.New("pkcs7: unsupported key encryption algorithm provided")
+
+// KeyEncryptionHash determines the crypto.Hash algorithm to use
+// when encrypting a content key. Change the value of this variable
+// to change which algorithm is used in the Encrypt() function.
+var KeyEncryptionHash = crypto.SHA256
+
+// ErrUnsupportedKeyEncryptionHash is returned when an
+// unsupported key encryption hash is provided.
+var ErrUnsupportedKeyEncryptionHash = errors.New("pkcs7: unsupported key encryption hash provided")
+
 // ErrPSKNotProvided is returned when attempting to encrypt
 // using a PSK without actually providing the PSK.
 var ErrPSKNotProvided = errors.New("pkcs7: cannot encrypt content: PSK not provided")
@@ -256,7 +275,7 @@ func encryptAESCBC(content []byte, key []byte) ([]byte, *encryptedContentInfo, e
 // value is EncryptionAlgorithmDESCBC. To use a different algorithm, change the
 // value before calling Encrypt(). For example:
 //
-//     ContentEncryptionAlgorithm = EncryptionAlgorithmAES128GCM
+//	ContentEncryptionAlgorithm = EncryptionAlgorithmAES256GCM
 //
 // TODO(fullsailor): Add support for encrypting content with other algorithms
 func Encrypt(content []byte, recipients []*x509.Certificate) ([]byte, error) {
@@ -288,7 +307,27 @@ func Encrypt(content []byte, recipients []*x509.Certificate) ([]byte, error) {
 	// Prepare each recipient's encrypted cipher key
 	recipientInfos := make([]recipientInfo, len(recipients))
 	for i, recipient := range recipients {
-		encrypted, err := encryptKey(key, recipient)
+		algorithm := KeyEncryptionAlgorithm
+		hash := KeyEncryptionHash
+		var kea pkix.AlgorithmIdentifier
+		switch {
+		case algorithm.Equal(OIDEncryptionAlgorithmRSAESOAEP):
+			parameters, err := getParametersForKeyEncryptionAlgorithm(algorithm, hash)
+			if err != nil {
+				return nil, fmt.Errorf("failed to get parameters for key encryption: %v", err)
+			}
+			kea = pkix.AlgorithmIdentifier{
+				Algorithm:  algorithm,
+				Parameters: parameters,
+			}
+		case algorithm.Equal(OIDEncryptionAlgorithmRSA):
+			kea = pkix.AlgorithmIdentifier{
+				Algorithm: algorithm,
+			}
+		default:
+			return nil, ErrUnsupportedKeyEncryptionAlgorithm
+		}
+		encrypted, err := encryptKey(key, recipient, algorithm, hash)
 		if err != nil {
 			return nil, err
 		}
@@ -297,12 +336,10 @@ func Encrypt(content []byte, recipients []*x509.Certificate) ([]byte, error) {
 			return nil, err
 		}
 		info := recipientInfo{
-			Version:               0,
-			IssuerAndSerialNumber: ias,
-			KeyEncryptionAlgorithm: pkix.AlgorithmIdentifier{
-				Algorithm: OIDEncryptionAlgorithmRSA,
-			},
-			EncryptedKey: encrypted,
+			Version:                0,
+			IssuerAndSerialNumber:  ias,
+			KeyEncryptionAlgorithm: kea,
+			EncryptedKey:           encrypted,
 		}
 		recipientInfos[i] = info
 	}
@@ -327,6 +364,37 @@ func Encrypt(content []byte, recipients []*x509.Certificate) ([]byte, error) {
 	return asn1.Marshal(wrapper)
 }
 
+func getParametersForKeyEncryptionAlgorithm(algorithm asn1.ObjectIdentifier, hash crypto.Hash) (asn1.RawValue, error) {
+	if !algorithm.Equal(OIDEncryptionAlgorithmRSAESOAEP) {
+		return asn1.RawValue{}, nil // return empty; not used
+	}
+
+	params := rsaOAEPAlgorithmParameters{}
+	switch hash {
+	case crypto.SHA1:
+		params.HashFunc = pkix.AlgorithmIdentifier{Algorithm: OIDDigestAlgorithmSHA1}
+	case crypto.SHA224:
+		params.HashFunc = pkix.AlgorithmIdentifier{Algorithm: OIDDigestAlgorithmSHA224}
+	case crypto.SHA256:
+		params.HashFunc = pkix.AlgorithmIdentifier{Algorithm: OIDDigestAlgorithmSHA256}
+	case crypto.SHA384:
+		params.HashFunc = pkix.AlgorithmIdentifier{Algorithm: OIDDigestAlgorithmSHA384}
+	case crypto.SHA512:
+		params.HashFunc = pkix.AlgorithmIdentifier{Algorithm: OIDDigestAlgorithmSHA512}
+	default:
+		return asn1.RawValue{}, ErrUnsupportedAlgorithm
+	}
+
+	b, err := asn1.Marshal(params)
+	if err != nil {
+		return asn1.RawValue{}, fmt.Errorf("failed marshaling key encryption parameters: %v", err)
+	}
+
+	return asn1.RawValue{
+		FullBytes: b,
+	}, nil
+}
+
 // EncryptUsingPSK creates and returns an encrypted data PKCS7 structure,
 // encrypted using caller provided pre-shared secret.
 func EncryptUsingPSK(content []byte, key []byte) ([]byte, error) {
@@ -375,15 +443,23 @@ func EncryptUsingPSK(content []byte, key []byte) ([]byte, error) {
 }
 
 func marshalEncryptedContent(content []byte) asn1.RawValue {
-	asn1Content, _ := asn1.Marshal(content)
-	return asn1.RawValue{Tag: 0, Class: 2, Bytes: asn1Content, IsCompound: true}
+	return asn1.RawValue{Bytes: content, Class: 2, IsCompound: false}
 }
 
-func encryptKey(key []byte, recipient *x509.Certificate) ([]byte, error) {
-	if pub := recipient.PublicKey.(*rsa.PublicKey); pub != nil {
+func encryptKey(key []byte, recipient *x509.Certificate, algorithm asn1.ObjectIdentifier, hash crypto.Hash) ([]byte, error) {
+	pub, ok := recipient.PublicKey.(*rsa.PublicKey)
+	if !ok {
+		return nil, ErrUnsupportedKeyType
+	}
+
+	switch {
+	case algorithm.Equal(OIDEncryptionAlgorithmRSA):
 		return rsa.EncryptPKCS1v15(rand.Reader, pub, key)
+	case algorithm.Equal(OIDEncryptionAlgorithmRSAESOAEP):
+		return rsa.EncryptOAEP(hash.New(), rand.Reader, pub, key, nil)
+	default:
+		return nil, ErrUnsupportedKeyEncryptionAlgorithm
 	}
-	return nil, ErrUnsupportedAlgorithm
 }
 
 func pad(data []byte, blocklen int) ([]byte, error) {
diff --git a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/debug.go b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/debug.go
new file mode 100644
index 0000000000..378cc265d2
--- /dev/null
+++ b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/debug.go
@@ -0,0 +1,14 @@
+package legacyx509
+
+import "fmt"
+
+// legacyGodebugSetting is a type mimicking Go's internal godebug package
+// settings, which are used to enable / disable certain functionalities at
+// build time.
+type legacyGodebugSetting int
+
+func (s legacyGodebugSetting) Value() string {
+	return fmt.Sprintf("%d", s)
+}
+
+func (s legacyGodebugSetting) IncNonDefault() {}
diff --git a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/doc.go b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/doc.go
new file mode 100644
index 0000000000..7d1469b6d0
--- /dev/null
+++ b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/doc.go
@@ -0,0 +1,14 @@
+/*
+Package legacyx509 is a copy of certain parts of Go's crypto/x509 package.
+It is based on Go 1.23, and has just the parts copied over required for
+parsing X509 certificates.
+
+The primary reason this copy exists is to keep support for parsing PKCS7
+messages containing Simple Certificate Enrolment Protocol (SCEP) requests
+from Windows devices. Go 1.23 made a change marking certificates with a
+critical authority key identifier as invalid, which is mandated by RFC 5280,
+but apparently Windows marks those specific certificates as such, resulting
+in those SCEP requests failing from being parsed correctly.
+*/
+
+package legacyx509
diff --git a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/oid.go b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/oid.go
new file mode 100644
index 0000000000..8268a07c50
--- /dev/null
+++ b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/oid.go
@@ -0,0 +1,377 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package legacyx509
+
+import (
+	"bytes"
+	"encoding/asn1"
+	"errors"
+	"math"
+	"math/big"
+	"math/bits"
+	"strconv"
+	"strings"
+)
+
+var (
+	errInvalidOID = errors.New("invalid oid")
+)
+
+// An OID represents an ASN.1 OBJECT IDENTIFIER.
+type OID struct {
+	der []byte
+}
+
+// ParseOID parses a Object Identifier string, represented by ASCII numbers separated by dots.
+func ParseOID(oid string) (OID, error) {
+	var o OID
+	return o, o.unmarshalOIDText(oid)
+}
+
+func newOIDFromDER(der []byte) (OID, bool) {
+	if len(der) == 0 || der[len(der)-1]&0x80 != 0 {
+		return OID{}, false
+	}
+
+	start := 0
+	for i, v := range der {
+		// ITU-T X.690, section 8.19.2:
+		// The subidentifier shall be encoded in the fewest possible octets,
+		// that is, the leading octet of the subidentifier shall not have the value 0x80.
+		if i == start && v == 0x80 {
+			return OID{}, false
+		}
+		if v&0x80 == 0 {
+			start = i + 1
+		}
+	}
+
+	return OID{der}, true
+}
+
+// OIDFromInts creates a new OID using ints, each integer is a separate component.
+func OIDFromInts(oid []uint64) (OID, error) {
+	if len(oid) < 2 || oid[0] > 2 || (oid[0] < 2 && oid[1] >= 40) {
+		return OID{}, errInvalidOID
+	}
+
+	length := base128IntLength(oid[0]*40 + oid[1])
+	for _, v := range oid[2:] {
+		length += base128IntLength(v)
+	}
+
+	der := make([]byte, 0, length)
+	der = appendBase128Int(der, oid[0]*40+oid[1])
+	for _, v := range oid[2:] {
+		der = appendBase128Int(der, v)
+	}
+	return OID{der}, nil
+}
+
+func base128IntLength(n uint64) int {
+	if n == 0 {
+		return 1
+	}
+	return (bits.Len64(n) + 6) / 7
+}
+
+func appendBase128Int(dst []byte, n uint64) []byte {
+	for i := base128IntLength(n) - 1; i >= 0; i-- {
+		o := byte(n >> uint(i*7))
+		o &= 0x7f
+		if i != 0 {
+			o |= 0x80
+		}
+		dst = append(dst, o)
+	}
+	return dst
+}
+
+func base128BigIntLength(n *big.Int) int {
+	if n.Cmp(big.NewInt(0)) == 0 {
+		return 1
+	}
+	return (n.BitLen() + 6) / 7
+}
+
+func appendBase128BigInt(dst []byte, n *big.Int) []byte {
+	if n.Cmp(big.NewInt(0)) == 0 {
+		return append(dst, 0)
+	}
+
+	for i := base128BigIntLength(n) - 1; i >= 0; i-- {
+		o := byte(big.NewInt(0).Rsh(n, uint(i)*7).Bits()[0])
+		o &= 0x7f
+		if i != 0 {
+			o |= 0x80
+		}
+		dst = append(dst, o)
+	}
+	return dst
+}
+
+// AppendText implements [encoding.TextAppender]
+func (o OID) AppendText(b []byte) ([]byte, error) {
+	return append(b, o.String()...), nil
+}
+
+// MarshalText implements [encoding.TextMarshaler]
+func (o OID) MarshalText() ([]byte, error) {
+	return o.AppendText(nil)
+}
+
+// UnmarshalText implements [encoding.TextUnmarshaler]
+func (o *OID) UnmarshalText(text []byte) error {
+	return o.unmarshalOIDText(string(text))
+}
+
+// cutString slices s around the first instance of sep,
+// returning the text before and after sep.
+// The found result reports whether sep appears in s.
+// If sep does not appear in s, cut returns s, "", false.
+func cutString(s, sep string) (before, after string, found bool) {
+	if i := strings.Index(s, sep); i >= 0 {
+		return s[:i], s[i+len(sep):], true
+	}
+	return s, "", false
+}
+
+func (o *OID) unmarshalOIDText(oid string) error {
+	// (*big.Int).SetString allows +/- signs, but we don't want
+	// to allow them in the string representation of Object Identifier, so
+	// reject such encodings.
+	for _, c := range oid {
+		isDigit := c >= '0' && c <= '9'
+		if !isDigit && c != '.' {
+			return errInvalidOID
+		}
+	}
+
+	var (
+		firstNum  string
+		secondNum string
+	)
+
+	var nextComponentExists bool
+	firstNum, oid, nextComponentExists = cutString(oid, ".")
+	if !nextComponentExists {
+		return errInvalidOID
+	}
+	secondNum, oid, nextComponentExists = cutString(oid, ".")
+
+	var (
+		first  = big.NewInt(0)
+		second = big.NewInt(0)
+	)
+
+	if _, ok := first.SetString(firstNum, 10); !ok {
+		return errInvalidOID
+	}
+	if _, ok := second.SetString(secondNum, 10); !ok {
+		return errInvalidOID
+	}
+
+	if first.Cmp(big.NewInt(2)) > 0 || (first.Cmp(big.NewInt(2)) < 0 && second.Cmp(big.NewInt(40)) >= 0) {
+		return errInvalidOID
+	}
+
+	firstComponent := first.Mul(first, big.NewInt(40))
+	firstComponent.Add(firstComponent, second)
+
+	der := appendBase128BigInt(make([]byte, 0, 32), firstComponent)
+
+	for nextComponentExists {
+		var strNum string
+		strNum, oid, nextComponentExists = cutString(oid, ".")
+		b, ok := big.NewInt(0).SetString(strNum, 10)
+		if !ok {
+			return errInvalidOID
+		}
+		der = appendBase128BigInt(der, b)
+	}
+
+	o.der = der
+	return nil
+}
+
+// AppendBinary implements [encoding.BinaryAppender]
+func (o OID) AppendBinary(b []byte) ([]byte, error) {
+	return append(b, o.der...), nil
+}
+
+// MarshalBinary implements [encoding.BinaryMarshaler]
+func (o OID) MarshalBinary() ([]byte, error) {
+	return o.AppendBinary(nil)
+}
+
+// cloneBytes returns a copy of b[:len(b)].
+// The result may have additional unused capacity.
+// Clone(nil) returns nil.
+func cloneBytes(b []byte) []byte {
+	if b == nil {
+		return nil
+	}
+	return append([]byte{}, b...)
+}
+
+// UnmarshalBinary implements [encoding.BinaryUnmarshaler]
+func (o *OID) UnmarshalBinary(b []byte) error {
+	oid, ok := newOIDFromDER(cloneBytes(b))
+	if !ok {
+		return errInvalidOID
+	}
+	*o = oid
+	return nil
+}
+
+// Equal returns true when oid and other represents the same Object Identifier.
+func (oid OID) Equal(other OID) bool {
+	// There is only one possible DER encoding of
+	// each unique Object Identifier.
+	return bytes.Equal(oid.der, other.der)
+}
+
+func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, failed bool) {
+	offset = initOffset
+	var ret64 int64
+	for shifted := 0; offset < len(bytes); shifted++ {
+		// 5 * 7 bits per byte == 35 bits of data
+		// Thus the representation is either non-minimal or too large for an int32
+		if shifted == 5 {
+			failed = true
+			return
+		}
+		ret64 <<= 7
+		b := bytes[offset]
+		// integers should be minimally encoded, so the leading octet should
+		// never be 0x80
+		if shifted == 0 && b == 0x80 {
+			failed = true
+			return
+		}
+		ret64 |= int64(b & 0x7f)
+		offset++
+		if b&0x80 == 0 {
+			ret = int(ret64)
+			// Ensure that the returned value fits in an int on all platforms
+			if ret64 > math.MaxInt32 {
+				failed = true
+			}
+			return
+		}
+	}
+	failed = true
+	return
+}
+
+// EqualASN1OID returns whether an OID equals an asn1.ObjectIdentifier. If
+// asn1.ObjectIdentifier cannot represent the OID specified by oid, because
+// a component of OID requires more than 31 bits, it returns false.
+func (oid OID) EqualASN1OID(other asn1.ObjectIdentifier) bool {
+	if len(other) < 2 {
+		return false
+	}
+	v, offset, failed := parseBase128Int(oid.der, 0)
+	if failed {
+		// This should never happen, since we've already parsed the OID,
+		// but just in case.
+		return false
+	}
+	if v < 80 {
+		a, b := v/40, v%40
+		if other[0] != a || other[1] != b {
+			return false
+		}
+	} else {
+		a, b := 2, v-80
+		if other[0] != a || other[1] != b {
+			return false
+		}
+	}
+
+	i := 2
+	for ; offset < len(oid.der); i++ {
+		v, offset, failed = parseBase128Int(oid.der, offset)
+		if failed {
+			// Again, shouldn't happen, since we've already parsed
+			// the OID, but better safe than sorry.
+			return false
+		}
+		if i >= len(other) || v != other[i] {
+			return false
+		}
+	}
+
+	return i == len(other)
+}
+
+// Strings returns the string representation of the Object Identifier.
+func (oid OID) String() string {
+	var b strings.Builder
+	b.Grow(32)
+	const (
+		valSize         = 64 // size in bits of val.
+		bitsPerByte     = 7
+		maxValSafeShift = (1 << (valSize - bitsPerByte)) - 1
+	)
+	var (
+		start    = 0
+		val      = uint64(0)
+		numBuf   = make([]byte, 0, 21)
+		bigVal   *big.Int
+		overflow bool
+	)
+	for i, v := range oid.der {
+		curVal := v & 0x7F
+		valEnd := v&0x80 == 0
+		if valEnd {
+			if start != 0 {
+				b.WriteByte('.')
+			}
+		}
+		if !overflow && val > maxValSafeShift {
+			if bigVal == nil {
+				bigVal = new(big.Int)
+			}
+			bigVal = bigVal.SetUint64(val)
+			overflow = true
+		}
+		if overflow {
+			bigVal = bigVal.Lsh(bigVal, bitsPerByte).Or(bigVal, big.NewInt(int64(curVal)))
+			if valEnd {
+				if start == 0 {
+					b.WriteString("2.")
+					bigVal = bigVal.Sub(bigVal, big.NewInt(80))
+				}
+				numBuf = bigVal.Append(numBuf, 10)
+				b.Write(numBuf)
+				numBuf = numBuf[:0]
+				val = 0
+				start = i + 1
+				overflow = false
+			}
+			continue
+		}
+		val <<= bitsPerByte
+		val |= uint64(curVal)
+		if valEnd {
+			if start == 0 {
+				if val < 80 {
+					b.Write(strconv.AppendUint(numBuf, val/40, 10))
+					b.WriteByte('.')
+					b.Write(strconv.AppendUint(numBuf, val%40, 10))
+				} else {
+					b.WriteString("2.")
+					b.Write(strconv.AppendUint(numBuf, val-80, 10))
+				}
+			} else {
+				b.Write(strconv.AppendUint(numBuf, val, 10))
+			}
+			val = 0
+			start = i + 1
+		}
+	}
+	return b.String()
+}
diff --git a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/parser.go b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/parser.go
new file mode 100644
index 0000000000..ec57e79f6e
--- /dev/null
+++ b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/parser.go
@@ -0,0 +1,1027 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package legacyx509
+
+import (
+	"bytes"
+	"crypto/dsa"
+	"crypto/ecdsa"
+	"crypto/ed25519"
+	"crypto/elliptic"
+	"crypto/rsa"
+	"crypto/x509/pkix"
+	"encoding/asn1"
+	"errors"
+	"fmt"
+	"math/big"
+	"net"
+	"net/url"
+	"strconv"
+	"strings"
+	"time"
+	"unicode/utf16"
+	"unicode/utf8"
+
+	"golang.org/x/crypto/cryptobyte"
+	cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
+
+	stdx509 "crypto/x509"
+)
+
+// ParseCertificates parses one or more certificates from the given ASN.1 DER
+// data. The certificates must be concatenated with no intermediate padding.
+func ParseCertificates(der []byte) ([]*stdx509.Certificate, error) {
+	var certs []*stdx509.Certificate
+	for len(der) > 0 {
+		cert, err := parseCertificate(der)
+		if err != nil {
+			return nil, err
+		}
+		certs = append(certs, cert)
+		der = der[len(cert.Raw):]
+	}
+	return certs, nil
+}
+
+// isPrintable reports whether the given b is in the ASN.1 PrintableString set.
+// This is a simplified version of encoding/asn1.isPrintable.
+func isPrintable(b byte) bool {
+	return 'a' <= b && b <= 'z' ||
+		'A' <= b && b <= 'Z' ||
+		'0' <= b && b <= '9' ||
+		'\'' <= b && b <= ')' ||
+		'+' <= b && b <= '/' ||
+		b == ' ' ||
+		b == ':' ||
+		b == '=' ||
+		b == '?' ||
+		// This is technically not allowed in a PrintableString.
+		// However, x509 certificates with wildcard strings don't
+		// always use the correct string type so we permit it.
+		b == '*' ||
+		// This is not technically allowed either. However, not
+		// only is it relatively common, but there are also a
+		// handful of CA certificates that contain it. At least
+		// one of which will not expire until 2027.
+		b == '&'
+}
+
+// parseASN1String parses the ASN.1 string types T61String, PrintableString,
+// UTF8String, BMPString, IA5String, and NumericString. This is mostly copied
+// from the respective encoding/asn1.parse... methods, rather than just
+// increasing the API surface of that package.
+func parseASN1String(tag cryptobyte_asn1.Tag, value []byte) (string, error) {
+	switch tag {
+	case cryptobyte_asn1.T61String:
+		return string(value), nil
+	case cryptobyte_asn1.PrintableString:
+		for _, b := range value {
+			if !isPrintable(b) {
+				return "", errors.New("invalid PrintableString")
+			}
+		}
+		return string(value), nil
+	case cryptobyte_asn1.UTF8String:
+		if !utf8.Valid(value) {
+			return "", errors.New("invalid UTF-8 string")
+		}
+		return string(value), nil
+	case cryptobyte_asn1.Tag(asn1.TagBMPString):
+		if len(value)%2 != 0 {
+			return "", errors.New("invalid BMPString")
+		}
+
+		// Strip terminator if present.
+		if l := len(value); l >= 2 && value[l-1] == 0 && value[l-2] == 0 {
+			value = value[:l-2]
+		}
+
+		s := make([]uint16, 0, len(value)/2)
+		for len(value) > 0 {
+			s = append(s, uint16(value[0])<<8+uint16(value[1]))
+			value = value[2:]
+		}
+
+		return string(utf16.Decode(s)), nil
+	case cryptobyte_asn1.IA5String:
+		s := string(value)
+		if isIA5String(s) != nil {
+			return "", errors.New("invalid IA5String")
+		}
+		return s, nil
+	case cryptobyte_asn1.Tag(asn1.TagNumericString):
+		for _, b := range value {
+			if !('0' <= b && b <= '9' || b == ' ') {
+				return "", errors.New("invalid NumericString")
+			}
+		}
+		return string(value), nil
+	}
+	return "", fmt.Errorf("unsupported string type: %v", tag)
+}
+
+// parseName parses a DER encoded Name as defined in RFC 5280. We may
+// want to export this function in the future for use in crypto/tls.
+func parseName(raw cryptobyte.String) (*pkix.RDNSequence, error) {
+	if !raw.ReadASN1(&raw, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: invalid RDNSequence")
+	}
+
+	var rdnSeq pkix.RDNSequence
+	for !raw.Empty() {
+		var rdnSet pkix.RelativeDistinguishedNameSET
+		var set cryptobyte.String
+		if !raw.ReadASN1(&set, cryptobyte_asn1.SET) {
+			return nil, errors.New("x509: invalid RDNSequence")
+		}
+		for !set.Empty() {
+			var atav cryptobyte.String
+			if !set.ReadASN1(&atav, cryptobyte_asn1.SEQUENCE) {
+				return nil, errors.New("x509: invalid RDNSequence: invalid attribute")
+			}
+			var attr pkix.AttributeTypeAndValue
+			if !atav.ReadASN1ObjectIdentifier(&attr.Type) {
+				return nil, errors.New("x509: invalid RDNSequence: invalid attribute type")
+			}
+			var rawValue cryptobyte.String
+			var valueTag cryptobyte_asn1.Tag
+			if !atav.ReadAnyASN1(&rawValue, &valueTag) {
+				return nil, errors.New("x509: invalid RDNSequence: invalid attribute value")
+			}
+			var err error
+			attr.Value, err = parseASN1String(valueTag, rawValue)
+			if err != nil {
+				return nil, fmt.Errorf("x509: invalid RDNSequence: invalid attribute value: %s", err)
+			}
+			rdnSet = append(rdnSet, attr)
+		}
+
+		rdnSeq = append(rdnSeq, rdnSet)
+	}
+
+	return &rdnSeq, nil
+}
+
+func parseAI(der cryptobyte.String) (pkix.AlgorithmIdentifier, error) {
+	ai := pkix.AlgorithmIdentifier{}
+	if !der.ReadASN1ObjectIdentifier(&ai.Algorithm) {
+		return ai, errors.New("x509: malformed OID")
+	}
+	if der.Empty() {
+		return ai, nil
+	}
+	var params cryptobyte.String
+	var tag cryptobyte_asn1.Tag
+	if !der.ReadAnyASN1Element(&params, &tag) {
+		return ai, errors.New("x509: malformed parameters")
+	}
+	ai.Parameters.Tag = int(tag)
+	ai.Parameters.FullBytes = params
+	return ai, nil
+}
+
+func parseTime(der *cryptobyte.String) (time.Time, error) {
+	var t time.Time
+	switch {
+	case der.PeekASN1Tag(cryptobyte_asn1.UTCTime):
+		if !der.ReadASN1UTCTime(&t) {
+			return t, errors.New("x509: malformed UTCTime")
+		}
+	case der.PeekASN1Tag(cryptobyte_asn1.GeneralizedTime):
+		if !der.ReadASN1GeneralizedTime(&t) {
+			return t, errors.New("x509: malformed GeneralizedTime")
+		}
+	default:
+		return t, errors.New("x509: unsupported time format")
+	}
+	return t, nil
+}
+
+func parseValidity(der cryptobyte.String) (time.Time, time.Time, error) {
+	notBefore, err := parseTime(&der)
+	if err != nil {
+		return time.Time{}, time.Time{}, err
+	}
+	notAfter, err := parseTime(&der)
+	if err != nil {
+		return time.Time{}, time.Time{}, err
+	}
+
+	return notBefore, notAfter, nil
+}
+
+func parseExtension(der cryptobyte.String) (pkix.Extension, error) {
+	var ext pkix.Extension
+	if !der.ReadASN1ObjectIdentifier(&ext.Id) {
+		return ext, errors.New("x509: malformed extension OID field")
+	}
+	if der.PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {
+		if !der.ReadASN1Boolean(&ext.Critical) {
+			return ext, errors.New("x509: malformed extension critical field")
+		}
+	}
+	var val cryptobyte.String
+	if !der.ReadASN1(&val, cryptobyte_asn1.OCTET_STRING) {
+		return ext, errors.New("x509: malformed extension value field")
+	}
+	ext.Value = val
+	return ext, nil
+}
+
+func parsePublicKey(keyData *publicKeyInfo) (interface{}, error) {
+	oid := keyData.Algorithm.Algorithm
+	params := keyData.Algorithm.Parameters
+	der := cryptobyte.String(keyData.PublicKey.RightAlign())
+	switch {
+	case oid.Equal(oidPublicKeyRSA):
+		// RSA public keys must have a NULL in the parameters.
+		// See RFC 3279, Section 2.3.1.
+		if !bytes.Equal(params.FullBytes, asn1.NullBytes) {
+			return nil, errors.New("x509: RSA key missing NULL parameters")
+		}
+
+		p := &pkcs1PublicKey{N: new(big.Int)}
+		if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
+			return nil, errors.New("x509: invalid RSA public key")
+		}
+		if !der.ReadASN1Integer(p.N) {
+			return nil, errors.New("x509: invalid RSA modulus")
+		}
+		if !der.ReadASN1Integer(&p.E) {
+			return nil, errors.New("x509: invalid RSA public exponent")
+		}
+
+		if p.N.Sign() <= 0 {
+			return nil, errors.New("x509: RSA modulus is not a positive number")
+		}
+		if p.E <= 0 {
+			return nil, errors.New("x509: RSA public exponent is not a positive number")
+		}
+
+		pub := &rsa.PublicKey{
+			E: p.E,
+			N: p.N,
+		}
+		return pub, nil
+	case oid.Equal(oidPublicKeyECDSA):
+		paramsDer := cryptobyte.String(params.FullBytes)
+		namedCurveOID := new(asn1.ObjectIdentifier)
+		if !paramsDer.ReadASN1ObjectIdentifier(namedCurveOID) {
+			return nil, errors.New("x509: invalid ECDSA parameters")
+		}
+		namedCurve := namedCurveFromOID(*namedCurveOID)
+		if namedCurve == nil {
+			return nil, errors.New("x509: unsupported elliptic curve")
+		}
+		x, y := elliptic.Unmarshal(namedCurve, der)
+		if x == nil {
+			return nil, errors.New("x509: failed to unmarshal elliptic curve point")
+		}
+		pub := &ecdsa.PublicKey{
+			Curve: namedCurve,
+			X:     x,
+			Y:     y,
+		}
+		return pub, nil
+	case oid.Equal(oidPublicKeyEd25519):
+		// RFC 8410, Section 3
+		// > For all of the OIDs, the parameters MUST be absent.
+		if len(params.FullBytes) != 0 {
+			return nil, errors.New("x509: Ed25519 key encoded with illegal parameters")
+		}
+		if len(der) != ed25519.PublicKeySize {
+			return nil, errors.New("x509: wrong Ed25519 public key size")
+		}
+		return ed25519.PublicKey(der), nil
+	// case oid.Equal(oidPublicKeyX25519):
+	// 	// RFC 8410, Section 3
+	// 	// > For all of the OIDs, the parameters MUST be absent.
+	// 	if len(params.FullBytes) != 0 {
+	// 		return nil, errors.New("x509: X25519 key encoded with illegal parameters")
+	// 	}
+	// 	return ecdh.X25519().NewPublicKey(der)
+	case oid.Equal(oidPublicKeyDSA):
+		y := new(big.Int)
+		if !der.ReadASN1Integer(y) {
+			return nil, errors.New("x509: invalid DSA public key")
+		}
+		pub := &dsa.PublicKey{
+			Y: y,
+			Parameters: dsa.Parameters{
+				P: new(big.Int),
+				Q: new(big.Int),
+				G: new(big.Int),
+			},
+		}
+		paramsDer := cryptobyte.String(params.FullBytes)
+		if !paramsDer.ReadASN1(&paramsDer, cryptobyte_asn1.SEQUENCE) ||
+			!paramsDer.ReadASN1Integer(pub.Parameters.P) ||
+			!paramsDer.ReadASN1Integer(pub.Parameters.Q) ||
+			!paramsDer.ReadASN1Integer(pub.Parameters.G) {
+			return nil, errors.New("x509: invalid DSA parameters")
+		}
+		if pub.Y.Sign() <= 0 || pub.Parameters.P.Sign() <= 0 ||
+			pub.Parameters.Q.Sign() <= 0 || pub.Parameters.G.Sign() <= 0 {
+			return nil, errors.New("x509: zero or negative DSA parameter")
+		}
+		return pub, nil
+	default:
+		return nil, errors.New("x509: unknown public key algorithm")
+	}
+}
+
+func parseKeyUsageExtension(der cryptobyte.String) (stdx509.KeyUsage, error) {
+	var usageBits asn1.BitString
+	if !der.ReadASN1BitString(&usageBits) {
+		return 0, errors.New("x509: invalid key usage")
+	}
+
+	var usage int
+	for i := 0; i < 9; i++ {
+		if usageBits.At(i) != 0 {
+			usage |= 1 << uint(i)
+		}
+	}
+	return stdx509.KeyUsage(usage), nil
+}
+
+func parseBasicConstraintsExtension(der cryptobyte.String) (bool, int, error) {
+	var isCA bool
+	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
+		return false, 0, errors.New("x509: invalid basic constraints")
+	}
+	if der.PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {
+		if !der.ReadASN1Boolean(&isCA) {
+			return false, 0, errors.New("x509: invalid basic constraints")
+		}
+	}
+	maxPathLen := -1
+	if der.PeekASN1Tag(cryptobyte_asn1.INTEGER) {
+		if !der.ReadASN1Integer(&maxPathLen) {
+			return false, 0, errors.New("x509: invalid basic constraints")
+		}
+	}
+
+	// TODO: map out.MaxPathLen to 0 if it has the -1 default value? (Issue 19285)
+	return isCA, maxPathLen, nil
+}
+
+func forEachSAN(der cryptobyte.String, callback func(tag int, data []byte) error) error {
+	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
+		return errors.New("x509: invalid subject alternative names")
+	}
+	for !der.Empty() {
+		var san cryptobyte.String
+		var tag cryptobyte_asn1.Tag
+		if !der.ReadAnyASN1(&san, &tag) {
+			return errors.New("x509: invalid subject alternative name")
+		}
+		if err := callback(int(tag^0x80), san); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func parseSANExtension(der cryptobyte.String) (dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL, err error) {
+	err = forEachSAN(der, func(tag int, data []byte) error {
+		switch tag {
+		case nameTypeEmail:
+			email := string(data)
+			if err := isIA5String(email); err != nil {
+				return errors.New("x509: SAN rfc822Name is malformed")
+			}
+			emailAddresses = append(emailAddresses, email)
+		case nameTypeDNS:
+			name := string(data)
+			if err := isIA5String(name); err != nil {
+				return errors.New("x509: SAN dNSName is malformed")
+			}
+			dnsNames = append(dnsNames, string(name))
+		case nameTypeURI:
+			uriStr := string(data)
+			if err := isIA5String(uriStr); err != nil {
+				return errors.New("x509: SAN uniformResourceIdentifier is malformed")
+			}
+			uri, err := url.Parse(uriStr)
+			if err != nil {
+				return fmt.Errorf("x509: cannot parse URI %q: %s", uriStr, err)
+			}
+			if len(uri.Host) > 0 {
+				if _, ok := domainToReverseLabels(uri.Host); !ok {
+					return fmt.Errorf("x509: cannot parse URI %q: invalid domain", uriStr)
+				}
+			}
+			uris = append(uris, uri)
+		case nameTypeIP:
+			switch len(data) {
+			case net.IPv4len, net.IPv6len:
+				ipAddresses = append(ipAddresses, data)
+			default:
+				return errors.New("x509: cannot parse IP address of length " + strconv.Itoa(len(data)))
+			}
+		}
+
+		return nil
+	})
+
+	return
+}
+
+func parseAuthorityKeyIdentifier(e pkix.Extension) ([]byte, error) {
+	// RFC 5280, Section 4.2.1.1
+	// if e.Critical {
+	// 	// Conforming CAs MUST mark this extension as non-critical
+	// 	return nil, errors.New("x509: authority key identifier incorrectly marked critical")
+	// }
+	val := cryptobyte.String(e.Value)
+	var akid cryptobyte.String
+	if !val.ReadASN1(&akid, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: invalid authority key identifier")
+	}
+	if akid.PeekASN1Tag(cryptobyte_asn1.Tag(0).ContextSpecific()) {
+		if !akid.ReadASN1(&akid, cryptobyte_asn1.Tag(0).ContextSpecific()) {
+			return nil, errors.New("x509: invalid authority key identifier")
+		}
+		return akid, nil
+	}
+	return nil, nil
+}
+
+func parseExtKeyUsageExtension(der cryptobyte.String) ([]stdx509.ExtKeyUsage, []asn1.ObjectIdentifier, error) {
+	var extKeyUsages []stdx509.ExtKeyUsage
+	var unknownUsages []asn1.ObjectIdentifier
+	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
+		return nil, nil, errors.New("x509: invalid extended key usages")
+	}
+	for !der.Empty() {
+		var eku asn1.ObjectIdentifier
+		if !der.ReadASN1ObjectIdentifier(&eku) {
+			return nil, nil, errors.New("x509: invalid extended key usages")
+		}
+		if extKeyUsage, ok := extKeyUsageFromOID(eku); ok {
+			extKeyUsages = append(extKeyUsages, stdx509.ExtKeyUsage(extKeyUsage))
+		} else {
+			unknownUsages = append(unknownUsages, eku)
+		}
+	}
+	return extKeyUsages, unknownUsages, nil
+}
+
+// func parseCertificatePoliciesExtension(der cryptobyte.String) ([]OID, error) {
+// 	var oids []OID
+// 	if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
+// 		return nil, errors.New("x509: invalid certificate policies")
+// 	}
+// 	for !der.Empty() {
+// 		var cp cryptobyte.String
+// 		var OIDBytes cryptobyte.String
+// 		if !der.ReadASN1(&cp, cryptobyte_asn1.SEQUENCE) || !cp.ReadASN1(&OIDBytes, cryptobyte_asn1.OBJECT_IDENTIFIER) {
+// 			return nil, errors.New("x509: invalid certificate policies")
+// 		}
+// 		oid, ok := newOIDFromDER(OIDBytes)
+// 		if !ok {
+// 			return nil, errors.New("x509: invalid certificate policies")
+// 		}
+// 		oids = append(oids, oid)
+// 	}
+// 	return oids, nil
+// }
+
+// isValidIPMask reports whether mask consists of zero or more 1 bits, followed by zero bits.
+func isValidIPMask(mask []byte) bool {
+	seenZero := false
+
+	for _, b := range mask {
+		if seenZero {
+			if b != 0 {
+				return false
+			}
+
+			continue
+		}
+
+		switch b {
+		case 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe:
+			seenZero = true
+		case 0xff:
+		default:
+			return false
+		}
+	}
+
+	return true
+}
+
+func parseNameConstraintsExtension(out *stdx509.Certificate, e pkix.Extension) (unhandled bool, err error) {
+	// RFC 5280, 4.2.1.10
+
+	// NameConstraints ::= SEQUENCE {
+	//      permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
+	//      excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
+	//
+	// GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+	//
+	// GeneralSubtree ::= SEQUENCE {
+	//      base                    GeneralName,
+	//      minimum         [0]     BaseDistance DEFAULT 0,
+	//      maximum         [1]     BaseDistance OPTIONAL }
+	//
+	// BaseDistance ::= INTEGER (0..MAX)
+
+	outer := cryptobyte.String(e.Value)
+	var toplevel, permitted, excluded cryptobyte.String
+	var havePermitted, haveExcluded bool
+	if !outer.ReadASN1(&toplevel, cryptobyte_asn1.SEQUENCE) ||
+		!outer.Empty() ||
+		!toplevel.ReadOptionalASN1(&permitted, &havePermitted, cryptobyte_asn1.Tag(0).ContextSpecific().Constructed()) ||
+		!toplevel.ReadOptionalASN1(&excluded, &haveExcluded, cryptobyte_asn1.Tag(1).ContextSpecific().Constructed()) ||
+		!toplevel.Empty() {
+		return false, errors.New("x509: invalid NameConstraints extension")
+	}
+
+	if !havePermitted && !haveExcluded || len(permitted) == 0 && len(excluded) == 0 {
+		// From RFC 5280, Section 4.2.1.10:
+		//   “either the permittedSubtrees field
+		//   or the excludedSubtrees MUST be
+		//   present”
+		return false, errors.New("x509: empty name constraints extension")
+	}
+
+	getValues := func(subtrees cryptobyte.String) (dnsNames []string, ips []*net.IPNet, emails, uriDomains []string, err error) {
+		for !subtrees.Empty() {
+			var seq, value cryptobyte.String
+			var tag cryptobyte_asn1.Tag
+			if !subtrees.ReadASN1(&seq, cryptobyte_asn1.SEQUENCE) ||
+				!seq.ReadAnyASN1(&value, &tag) {
+				return nil, nil, nil, nil, fmt.Errorf("x509: invalid NameConstraints extension")
+			}
+
+			var (
+				dnsTag   = cryptobyte_asn1.Tag(2).ContextSpecific()
+				emailTag = cryptobyte_asn1.Tag(1).ContextSpecific()
+				ipTag    = cryptobyte_asn1.Tag(7).ContextSpecific()
+				uriTag   = cryptobyte_asn1.Tag(6).ContextSpecific()
+			)
+
+			switch tag {
+			case dnsTag:
+				domain := string(value)
+				if err := isIA5String(domain); err != nil {
+					return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
+				}
+
+				trimmedDomain := domain
+				if len(trimmedDomain) > 0 && trimmedDomain[0] == '.' {
+					// constraints can have a leading
+					// period to exclude the domain
+					// itself, but that's not valid in a
+					// normal domain name.
+					trimmedDomain = trimmedDomain[1:]
+				}
+				if _, ok := domainToReverseLabels(trimmedDomain); !ok {
+					return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse dnsName constraint %q", domain)
+				}
+				dnsNames = append(dnsNames, domain)
+
+			case ipTag:
+				l := len(value)
+				var ip, mask []byte
+
+				switch l {
+				case 8:
+					ip = value[:4]
+					mask = value[4:]
+
+				case 32:
+					ip = value[:16]
+					mask = value[16:]
+
+				default:
+					return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained value of length %d", l)
+				}
+
+				if !isValidIPMask(mask) {
+					return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained invalid mask %x", mask)
+				}
+
+				ips = append(ips, &net.IPNet{IP: net.IP(ip), Mask: net.IPMask(mask)})
+
+			case emailTag:
+				constraint := string(value)
+				if err := isIA5String(constraint); err != nil {
+					return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
+				}
+
+				// If the constraint contains an @ then
+				// it specifies an exact mailbox name.
+				if strings.Contains(constraint, "@") {
+					if _, ok := parseRFC2821Mailbox(constraint); !ok {
+						return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)
+					}
+				} else {
+					// Otherwise it's a domain name.
+					domain := constraint
+					if len(domain) > 0 && domain[0] == '.' {
+						domain = domain[1:]
+					}
+					if _, ok := domainToReverseLabels(domain); !ok {
+						return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)
+					}
+				}
+				emails = append(emails, constraint)
+
+			case uriTag:
+				domain := string(value)
+				if err := isIA5String(domain); err != nil {
+					return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
+				}
+
+				if net.ParseIP(domain) != nil {
+					return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q: cannot be IP address", domain)
+				}
+
+				trimmedDomain := domain
+				if len(trimmedDomain) > 0 && trimmedDomain[0] == '.' {
+					// constraints can have a leading
+					// period to exclude the domain itself,
+					// but that's not valid in a normal
+					// domain name.
+					trimmedDomain = trimmedDomain[1:]
+				}
+				if _, ok := domainToReverseLabels(trimmedDomain); !ok {
+					return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q", domain)
+				}
+				uriDomains = append(uriDomains, domain)
+
+			default:
+				unhandled = true
+			}
+		}
+
+		return dnsNames, ips, emails, uriDomains, nil
+	}
+
+	if out.PermittedDNSDomains, out.PermittedIPRanges, out.PermittedEmailAddresses, out.PermittedURIDomains, err = getValues(permitted); err != nil {
+		return false, err
+	}
+	if out.ExcludedDNSDomains, out.ExcludedIPRanges, out.ExcludedEmailAddresses, out.ExcludedURIDomains, err = getValues(excluded); err != nil {
+		return false, err
+	}
+	out.PermittedDNSDomainsCritical = e.Critical
+
+	return unhandled, nil
+}
+
+func processExtensions(out *stdx509.Certificate) error {
+	var err error
+	for _, e := range out.Extensions {
+		unhandled := false
+
+		if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 {
+			switch e.Id[3] {
+			case 15:
+				out.KeyUsage, err = parseKeyUsageExtension(e.Value)
+				if err != nil {
+					return err
+				}
+			case 19:
+				out.IsCA, out.MaxPathLen, err = parseBasicConstraintsExtension(e.Value)
+				if err != nil {
+					return err
+				}
+				out.BasicConstraintsValid = true
+				out.MaxPathLenZero = out.MaxPathLen == 0
+			case 17:
+				out.DNSNames, out.EmailAddresses, out.IPAddresses, out.URIs, err = parseSANExtension(e.Value)
+				if err != nil {
+					return err
+				}
+
+				if len(out.DNSNames) == 0 && len(out.EmailAddresses) == 0 && len(out.IPAddresses) == 0 && len(out.URIs) == 0 {
+					// If we didn't parse anything then we do the critical check, below.
+					unhandled = true
+				}
+
+			case 30:
+				unhandled, err = parseNameConstraintsExtension(out, e)
+				if err != nil {
+					return err
+				}
+
+			case 31:
+				// RFC 5280, 4.2.1.13
+
+				// CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
+				//
+				// DistributionPoint ::= SEQUENCE {
+				//     distributionPoint       [0]     DistributionPointName OPTIONAL,
+				//     reasons                 [1]     ReasonFlags OPTIONAL,
+				//     cRLIssuer               [2]     GeneralNames OPTIONAL }
+				//
+				// DistributionPointName ::= CHOICE {
+				//     fullName                [0]     GeneralNames,
+				//     nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
+				val := cryptobyte.String(e.Value)
+				if !val.ReadASN1(&val, cryptobyte_asn1.SEQUENCE) {
+					return errors.New("x509: invalid CRL distribution points")
+				}
+				for !val.Empty() {
+					var dpDER cryptobyte.String
+					if !val.ReadASN1(&dpDER, cryptobyte_asn1.SEQUENCE) {
+						return errors.New("x509: invalid CRL distribution point")
+					}
+					var dpNameDER cryptobyte.String
+					var dpNamePresent bool
+					if !dpDER.ReadOptionalASN1(&dpNameDER, &dpNamePresent, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
+						return errors.New("x509: invalid CRL distribution point")
+					}
+					if !dpNamePresent {
+						continue
+					}
+					if !dpNameDER.ReadASN1(&dpNameDER, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
+						return errors.New("x509: invalid CRL distribution point")
+					}
+					for !dpNameDER.Empty() {
+						if !dpNameDER.PeekASN1Tag(cryptobyte_asn1.Tag(6).ContextSpecific()) {
+							break
+						}
+						var uri cryptobyte.String
+						if !dpNameDER.ReadASN1(&uri, cryptobyte_asn1.Tag(6).ContextSpecific()) {
+							return errors.New("x509: invalid CRL distribution point")
+						}
+						out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(uri))
+					}
+				}
+
+			case 35:
+				out.AuthorityKeyId, err = parseAuthorityKeyIdentifier(e)
+				if err != nil {
+					return err
+				}
+			case 37:
+				out.ExtKeyUsage, out.UnknownExtKeyUsage, err = parseExtKeyUsageExtension(e.Value)
+				if err != nil {
+					return err
+				}
+			case 14:
+				// RFC 5280, 4.2.1.2
+				if e.Critical {
+					// Conforming CAs MUST mark this extension as non-critical
+					return errors.New("x509: subject key identifier incorrectly marked critical")
+				}
+				val := cryptobyte.String(e.Value)
+				var skid cryptobyte.String
+				if !val.ReadASN1(&skid, cryptobyte_asn1.OCTET_STRING) {
+					return errors.New("x509: invalid subject key identifier")
+				}
+				out.SubjectKeyId = skid
+			// case 32:
+			// 	out.Policies, err = parseCertificatePoliciesExtension(e.Value)
+			// 	if err != nil {
+			// 		return err
+			// 	}
+			// 	out.PolicyIdentifiers = make([]asn1.ObjectIdentifier, 0, len(out.Policies))
+			// 	for _, oid := range out.Policies {
+			// 		if oid, ok := oid.toASN1OID(); ok {
+			// 			out.PolicyIdentifiers = append(out.PolicyIdentifiers, oid)
+			// 		}
+			// 	}
+			default:
+				// Unknown extensions are recorded if critical.
+				unhandled = true
+			}
+		} else if e.Id.Equal(oidExtensionAuthorityInfoAccess) {
+			// RFC 5280 4.2.2.1: Authority Information Access
+			if e.Critical {
+				// Conforming CAs MUST mark this extension as non-critical
+				return errors.New("x509: authority info access incorrectly marked critical")
+			}
+			val := cryptobyte.String(e.Value)
+			if !val.ReadASN1(&val, cryptobyte_asn1.SEQUENCE) {
+				return errors.New("x509: invalid authority info access")
+			}
+			for !val.Empty() {
+				var aiaDER cryptobyte.String
+				if !val.ReadASN1(&aiaDER, cryptobyte_asn1.SEQUENCE) {
+					return errors.New("x509: invalid authority info access")
+				}
+				var method asn1.ObjectIdentifier
+				if !aiaDER.ReadASN1ObjectIdentifier(&method) {
+					return errors.New("x509: invalid authority info access")
+				}
+				if !aiaDER.PeekASN1Tag(cryptobyte_asn1.Tag(6).ContextSpecific()) {
+					continue
+				}
+				if !aiaDER.ReadASN1(&aiaDER, cryptobyte_asn1.Tag(6).ContextSpecific()) {
+					return errors.New("x509: invalid authority info access")
+				}
+				switch {
+				case method.Equal(oidAuthorityInfoAccessOcsp):
+					out.OCSPServer = append(out.OCSPServer, string(aiaDER))
+				case method.Equal(oidAuthorityInfoAccessIssuers):
+					out.IssuingCertificateURL = append(out.IssuingCertificateURL, string(aiaDER))
+				}
+			}
+		} else {
+			// Unknown extensions are recorded if critical.
+			unhandled = true
+		}
+
+		if e.Critical && unhandled {
+			out.UnhandledCriticalExtensions = append(out.UnhandledCriticalExtensions, e.Id)
+		}
+	}
+
+	return nil
+}
+
+var x509negativeserial = legacyGodebugSetting(0) // replaces godebug.New("x509negativeserial")
+
+func parseCertificate(der []byte) (*stdx509.Certificate, error) {
+	cert := &stdx509.Certificate{}
+
+	input := cryptobyte.String(der)
+	// we read the SEQUENCE including length and tag bytes so that
+	// we can populate Certificate.Raw, before unwrapping the
+	// SEQUENCE so it can be operated on
+	if !input.ReadASN1Element(&input, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed certificate")
+	}
+	cert.Raw = input
+	if !input.ReadASN1(&input, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed certificate")
+	}
+
+	var tbs cryptobyte.String
+	// do the same trick again as above to extract the raw
+	// bytes for Certificate.RawTBSCertificate
+	if !input.ReadASN1Element(&tbs, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed tbs certificate")
+	}
+	cert.RawTBSCertificate = tbs
+	if !tbs.ReadASN1(&tbs, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed tbs certificate")
+	}
+
+	if !tbs.ReadOptionalASN1Integer(&cert.Version, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific(), 0) {
+		return nil, errors.New("x509: malformed version")
+	}
+	if cert.Version < 0 {
+		return nil, errors.New("x509: malformed version")
+	}
+	// for backwards compat reasons Version is one-indexed,
+	// rather than zero-indexed as defined in 5280
+	cert.Version++
+	if cert.Version > 3 {
+		return nil, errors.New("x509: invalid version")
+	}
+
+	serial := new(big.Int)
+	if !tbs.ReadASN1Integer(serial) {
+		return nil, errors.New("x509: malformed serial number")
+	}
+	if serial.Sign() == -1 {
+		if x509negativeserial.Value() != "1" {
+			return nil, errors.New("x509: negative serial number")
+		} else {
+			x509negativeserial.IncNonDefault()
+		}
+	}
+	cert.SerialNumber = serial
+
+	var sigAISeq cryptobyte.String
+	if !tbs.ReadASN1(&sigAISeq, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed signature algorithm identifier")
+	}
+	// Before parsing the inner algorithm identifier, extract
+	// the outer algorithm identifier and make sure that they
+	// match.
+	var outerSigAISeq cryptobyte.String
+	if !input.ReadASN1(&outerSigAISeq, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed algorithm identifier")
+	}
+	if !bytes.Equal(outerSigAISeq, sigAISeq) {
+		return nil, errors.New("x509: inner and outer signature algorithm identifiers don't match")
+	}
+	sigAI, err := parseAI(sigAISeq)
+	if err != nil {
+		return nil, err
+	}
+	cert.SignatureAlgorithm = getSignatureAlgorithmFromAI(sigAI)
+
+	var issuerSeq cryptobyte.String
+	if !tbs.ReadASN1Element(&issuerSeq, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed issuer")
+	}
+	cert.RawIssuer = issuerSeq
+	issuerRDNs, err := parseName(issuerSeq)
+	if err != nil {
+		return nil, err
+	}
+	cert.Issuer.FillFromRDNSequence(issuerRDNs)
+
+	var validity cryptobyte.String
+	if !tbs.ReadASN1(&validity, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed validity")
+	}
+	cert.NotBefore, cert.NotAfter, err = parseValidity(validity)
+	if err != nil {
+		return nil, err
+	}
+
+	var subjectSeq cryptobyte.String
+	if !tbs.ReadASN1Element(&subjectSeq, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed issuer")
+	}
+	cert.RawSubject = subjectSeq
+	subjectRDNs, err := parseName(subjectSeq)
+	if err != nil {
+		return nil, err
+	}
+	cert.Subject.FillFromRDNSequence(subjectRDNs)
+
+	var spki cryptobyte.String
+	if !tbs.ReadASN1Element(&spki, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed spki")
+	}
+	cert.RawSubjectPublicKeyInfo = spki
+	if !spki.ReadASN1(&spki, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed spki")
+	}
+	var pkAISeq cryptobyte.String
+	if !spki.ReadASN1(&pkAISeq, cryptobyte_asn1.SEQUENCE) {
+		return nil, errors.New("x509: malformed public key algorithm identifier")
+	}
+	pkAI, err := parseAI(pkAISeq)
+	if err != nil {
+		return nil, err
+	}
+	cert.PublicKeyAlgorithm = getPublicKeyAlgorithmFromOID(pkAI.Algorithm)
+	var spk asn1.BitString
+	if !spki.ReadASN1BitString(&spk) {
+		return nil, errors.New("x509: malformed subjectPublicKey")
+	}
+	if cert.PublicKeyAlgorithm != stdx509.UnknownPublicKeyAlgorithm {
+		cert.PublicKey, err = parsePublicKey(&publicKeyInfo{
+			Algorithm: pkAI,
+			PublicKey: spk,
+		})
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	if cert.Version > 1 {
+		if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(1).ContextSpecific()) {
+			return nil, errors.New("x509: malformed issuerUniqueID")
+		}
+		if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(2).ContextSpecific()) {
+			return nil, errors.New("x509: malformed subjectUniqueID")
+		}
+		if cert.Version == 3 {
+			var extensions cryptobyte.String
+			var present bool
+			if !tbs.ReadOptionalASN1(&extensions, &present, cryptobyte_asn1.Tag(3).Constructed().ContextSpecific()) {
+				return nil, errors.New("x509: malformed extensions")
+			}
+			if present {
+				seenExts := make(map[string]bool)
+				if !extensions.ReadASN1(&extensions, cryptobyte_asn1.SEQUENCE) {
+					return nil, errors.New("x509: malformed extensions")
+				}
+				for !extensions.Empty() {
+					var extension cryptobyte.String
+					if !extensions.ReadASN1(&extension, cryptobyte_asn1.SEQUENCE) {
+						return nil, errors.New("x509: malformed extension")
+					}
+					ext, err := parseExtension(extension)
+					if err != nil {
+						return nil, err
+					}
+					oidStr := ext.Id.String()
+					if seenExts[oidStr] {
+						return nil, fmt.Errorf("x509: certificate contains duplicate extension with OID %q", oidStr)
+					}
+					seenExts[oidStr] = true
+					cert.Extensions = append(cert.Extensions, ext)
+				}
+				err = processExtensions(cert)
+				if err != nil {
+					return nil, err
+				}
+			}
+		}
+	}
+
+	var signature asn1.BitString
+	if !input.ReadASN1BitString(&signature) {
+		return nil, errors.New("x509: malformed signature")
+	}
+	cert.Signature = signature.RightAlign()
+
+	return cert, nil
+}
diff --git a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/pkcs1.go b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/pkcs1.go
new file mode 100644
index 0000000000..da3c38a4e4
--- /dev/null
+++ b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/pkcs1.go
@@ -0,0 +1,15 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package legacyx509
+
+import (
+	"math/big"
+)
+
+// pkcs1PublicKey reflects the ASN.1 structure of a PKCS #1 public key.
+type pkcs1PublicKey struct {
+	N *big.Int
+	E int
+}
diff --git a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/verify.go b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/verify.go
new file mode 100644
index 0000000000..901e3ba85b
--- /dev/null
+++ b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/verify.go
@@ -0,0 +1,193 @@
+package legacyx509
+
+import (
+	"bytes"
+	"strings"
+)
+
+// rfc2821Mailbox represents a “mailbox” (which is an email address to most
+// people) by breaking it into the “local” (i.e. before the '@') and “domain”
+// parts.
+type rfc2821Mailbox struct {
+	local, domain string
+}
+
+// parseRFC2821Mailbox parses an email address into local and domain parts,
+// based on the ABNF for a “Mailbox” from RFC 2821. According to RFC 5280,
+// Section 4.2.1.6 that's correct for an rfc822Name from a certificate: “The
+// format of an rfc822Name is a "Mailbox" as defined in RFC 2821, Section 4.1.2”.
+func parseRFC2821Mailbox(in string) (mailbox rfc2821Mailbox, ok bool) {
+	if len(in) == 0 {
+		return mailbox, false
+	}
+
+	localPartBytes := make([]byte, 0, len(in)/2)
+
+	if in[0] == '"' {
+		// Quoted-string = DQUOTE *qcontent DQUOTE
+		// non-whitespace-control = %d1-8 / %d11 / %d12 / %d14-31 / %d127
+		// qcontent = qtext / quoted-pair
+		// qtext = non-whitespace-control /
+		//         %d33 / %d35-91 / %d93-126
+		// quoted-pair = ("\" text) / obs-qp
+		// text = %d1-9 / %d11 / %d12 / %d14-127 / obs-text
+		//
+		// (Names beginning with “obs-” are the obsolete syntax from RFC 2822,
+		// Section 4. Since it has been 16 years, we no longer accept that.)
+		in = in[1:]
+	QuotedString:
+		for {
+			if len(in) == 0 {
+				return mailbox, false
+			}
+			c := in[0]
+			in = in[1:]
+
+			switch {
+			case c == '"':
+				break QuotedString
+
+			case c == '\\':
+				// quoted-pair
+				if len(in) == 0 {
+					return mailbox, false
+				}
+				if in[0] == 11 ||
+					in[0] == 12 ||
+					(1 <= in[0] && in[0] <= 9) ||
+					(14 <= in[0] && in[0] <= 127) {
+					localPartBytes = append(localPartBytes, in[0])
+					in = in[1:]
+				} else {
+					return mailbox, false
+				}
+
+			case c == 11 ||
+				c == 12 ||
+				// Space (char 32) is not allowed based on the
+				// BNF, but RFC 3696 gives an example that
+				// assumes that it is. Several “verified”
+				// errata continue to argue about this point.
+				// We choose to accept it.
+				c == 32 ||
+				c == 33 ||
+				c == 127 ||
+				(1 <= c && c <= 8) ||
+				(14 <= c && c <= 31) ||
+				(35 <= c && c <= 91) ||
+				(93 <= c && c <= 126):
+				// qtext
+				localPartBytes = append(localPartBytes, c)
+
+			default:
+				return mailbox, false
+			}
+		}
+	} else {
+		// Atom ("." Atom)*
+	NextChar:
+		for len(in) > 0 {
+			// atext from RFC 2822, Section 3.2.4
+			c := in[0]
+
+			switch {
+			case c == '\\':
+				// Examples given in RFC 3696 suggest that
+				// escaped characters can appear outside of a
+				// quoted string. Several “verified” errata
+				// continue to argue the point. We choose to
+				// accept it.
+				in = in[1:]
+				if len(in) == 0 {
+					return mailbox, false
+				}
+				fallthrough
+
+			case ('0' <= c && c <= '9') ||
+				('a' <= c && c <= 'z') ||
+				('A' <= c && c <= 'Z') ||
+				c == '!' || c == '#' || c == '$' || c == '%' ||
+				c == '&' || c == '\'' || c == '*' || c == '+' ||
+				c == '-' || c == '/' || c == '=' || c == '?' ||
+				c == '^' || c == '_' || c == '`' || c == '{' ||
+				c == '|' || c == '}' || c == '~' || c == '.':
+				localPartBytes = append(localPartBytes, in[0])
+				in = in[1:]
+
+			default:
+				break NextChar
+			}
+		}
+
+		if len(localPartBytes) == 0 {
+			return mailbox, false
+		}
+
+		// From RFC 3696, Section 3:
+		// “period (".") may also appear, but may not be used to start
+		// or end the local part, nor may two or more consecutive
+		// periods appear.”
+		twoDots := []byte{'.', '.'}
+		if localPartBytes[0] == '.' ||
+			localPartBytes[len(localPartBytes)-1] == '.' ||
+			bytes.Contains(localPartBytes, twoDots) {
+			return mailbox, false
+		}
+	}
+
+	if len(in) == 0 || in[0] != '@' {
+		return mailbox, false
+	}
+	in = in[1:]
+
+	// The RFC species a format for domains, but that's known to be
+	// violated in practice so we accept that anything after an '@' is the
+	// domain part.
+	if _, ok := domainToReverseLabels(in); !ok {
+		return mailbox, false
+	}
+
+	mailbox.local = string(localPartBytes)
+	mailbox.domain = in
+	return mailbox, true
+}
+
+// domainToReverseLabels converts a textual domain name like foo.example.com to
+// the list of labels in reverse order, e.g. ["com", "example", "foo"].
+func domainToReverseLabels(domain string) (reverseLabels []string, ok bool) {
+	for len(domain) > 0 {
+		if i := strings.LastIndexByte(domain, '.'); i == -1 {
+			reverseLabels = append(reverseLabels, domain)
+			domain = ""
+		} else {
+			reverseLabels = append(reverseLabels, domain[i+1:])
+			domain = domain[:i]
+			if i == 0 { // domain == ""
+				// domain is prefixed with an empty label, append an empty
+				// string to reverseLabels to indicate this.
+				reverseLabels = append(reverseLabels, "")
+			}
+		}
+	}
+
+	if len(reverseLabels) > 0 && len(reverseLabels[0]) == 0 {
+		// An empty label at the end indicates an absolute value.
+		return nil, false
+	}
+
+	for _, label := range reverseLabels {
+		if len(label) == 0 {
+			// Empty labels are otherwise invalid.
+			return nil, false
+		}
+
+		for _, c := range label {
+			if c < 33 || c > 126 {
+				// Invalid character.
+				return nil, false
+			}
+		}
+	}
+
+	return reverseLabels, true
+}
diff --git a/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/x509.go b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/x509.go
new file mode 100644
index 0000000000..a4500bfb17
--- /dev/null
+++ b/vendor/github.com/smallstep/pkcs7/internal/legacy/x509/x509.go
@@ -0,0 +1,488 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package x509 implements a subset of the X.509 standard.
+//
+// It allows parsing and generating certificates, certificate signing
+// requests, certificate revocation lists, and encoded public and private keys.
+// It provides a certificate verifier, complete with a chain builder.
+//
+// The package targets the X.509 technical profile defined by the IETF (RFC
+// 2459/3280/5280), and as further restricted by the CA/Browser Forum Baseline
+// Requirements. There is minimal support for features outside of these
+// profiles, as the primary goal of the package is to provide compatibility
+// with the publicly trusted TLS certificate ecosystem and its policies and
+// constraints.
+//
+// On macOS and Windows, certificate verification is handled by system APIs, but
+// the package aims to apply consistent validation rules across operating
+// systems.
+package legacyx509
+
+import (
+	"bytes"
+	"crypto"
+	"crypto/elliptic"
+	stdx509 "crypto/x509"
+	"crypto/x509/pkix"
+	"encoding/asn1"
+	"fmt"
+	"strconv"
+	"unicode"
+
+	// Explicitly import these for their crypto.RegisterHash init side-effects.
+	// Keep these as blank imports, even if they're imported above.
+	_ "crypto/sha1"
+	_ "crypto/sha256"
+	_ "crypto/sha512"
+)
+
+type publicKeyInfo struct {
+	Raw       asn1.RawContent
+	Algorithm pkix.AlgorithmIdentifier
+	PublicKey asn1.BitString
+}
+
+type SignatureAlgorithm int
+
+const (
+	UnknownSignatureAlgorithm SignatureAlgorithm = iota
+
+	MD2WithRSA  // Unsupported.
+	MD5WithRSA  // Only supported for signing, not verification.
+	SHA1WithRSA // Only supported for signing, and verification of CRLs, CSRs, and OCSP responses.
+	SHA256WithRSA
+	SHA384WithRSA
+	SHA512WithRSA
+	DSAWithSHA1   // Unsupported.
+	DSAWithSHA256 // Unsupported.
+	ECDSAWithSHA1 // Only supported for signing, and verification of CRLs, CSRs, and OCSP responses.
+	ECDSAWithSHA256
+	ECDSAWithSHA384
+	ECDSAWithSHA512
+	SHA256WithRSAPSS
+	SHA384WithRSAPSS
+	SHA512WithRSAPSS
+	PureEd25519
+)
+
+func (algo SignatureAlgorithm) String() string {
+	for _, details := range signatureAlgorithmDetails {
+		if details.algo == algo {
+			return details.name
+		}
+	}
+	return strconv.Itoa(int(algo))
+}
+
+type PublicKeyAlgorithm int
+
+const (
+	UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota
+	RSA
+	DSA // Only supported for parsing.
+	ECDSA
+	Ed25519
+)
+
+var publicKeyAlgoName = [...]string{
+	RSA:     "RSA",
+	DSA:     "DSA",
+	ECDSA:   "ECDSA",
+	Ed25519: "Ed25519",
+}
+
+func (algo PublicKeyAlgorithm) String() string {
+	if 0 < algo && int(algo) < len(publicKeyAlgoName) {
+		return publicKeyAlgoName[algo]
+	}
+	return strconv.Itoa(int(algo))
+}
+
+// OIDs for signature algorithms
+//
+//	pkcs-1 OBJECT IDENTIFIER ::= {
+//		iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
+//
+// RFC 3279 2.2.1 RSA Signature Algorithms
+//
+//	md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
+//
+//	sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
+//
+//	dsaWithSha1 OBJECT IDENTIFIER ::= {
+//		iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3 }
+//
+// RFC 3279 2.2.3 ECDSA Signature Algorithm
+//
+//	ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
+//		iso(1) member-body(2) us(840) ansi-x962(10045)
+//		signatures(4) ecdsa-with-SHA1(1)}
+//
+// RFC 4055 5 PKCS #1 Version 1.5
+//
+//	sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
+//
+//	sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
+//
+//	sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
+//
+// RFC 5758 3.1 DSA Signature Algorithms
+//
+//	dsaWithSha256 OBJECT IDENTIFIER ::= {
+//		joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101)
+//		csor(3) algorithms(4) id-dsa-with-sha2(3) 2}
+//
+// RFC 5758 3.2 ECDSA Signature Algorithm
+//
+//	ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+//		us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
+//
+//	ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+//		us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 }
+//
+//	ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+//		us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 }
+//
+// RFC 8410 3 Curve25519 and Curve448 Algorithm Identifiers
+//
+//	id-Ed25519   OBJECT IDENTIFIER ::= { 1 3 101 112 }
+var (
+	oidSignatureMD5WithRSA      = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}
+	oidSignatureSHA1WithRSA     = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
+	oidSignatureSHA256WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
+	oidSignatureSHA384WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
+	oidSignatureSHA512WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
+	oidSignatureRSAPSS          = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10}
+	oidSignatureDSAWithSHA1     = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
+	oidSignatureDSAWithSHA256   = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2}
+	oidSignatureECDSAWithSHA1   = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}
+	oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
+	oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
+	oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}
+	oidSignatureEd25519         = asn1.ObjectIdentifier{1, 3, 101, 112}
+
+	oidSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}
+	oidSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2}
+	oidSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3}
+
+	oidMGF1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 8}
+
+	// oidISOSignatureSHA1WithRSA means the same as oidSignatureSHA1WithRSA
+	// but it's specified by ISO. Microsoft's makecert.exe has been known
+	// to produce certificates with this OID.
+	oidISOSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 29}
+)
+
+var signatureAlgorithmDetails = []struct {
+	algo       SignatureAlgorithm
+	name       string
+	oid        asn1.ObjectIdentifier
+	params     asn1.RawValue
+	pubKeyAlgo PublicKeyAlgorithm
+	hash       crypto.Hash
+	isRSAPSS   bool
+}{
+	{MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, asn1.NullRawValue, RSA, crypto.MD5, false},
+	{SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, asn1.NullRawValue, RSA, crypto.SHA1, false},
+	{SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, asn1.NullRawValue, RSA, crypto.SHA1, false},
+	{SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, asn1.NullRawValue, RSA, crypto.SHA256, false},
+	{SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, asn1.NullRawValue, RSA, crypto.SHA384, false},
+	{SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, asn1.NullRawValue, RSA, crypto.SHA512, false},
+	{SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, pssParametersSHA256, RSA, crypto.SHA256, true},
+	{SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, pssParametersSHA384, RSA, crypto.SHA384, true},
+	{SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, pssParametersSHA512, RSA, crypto.SHA512, true},
+	{DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, emptyRawValue, DSA, crypto.SHA1, false},
+	{DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, emptyRawValue, DSA, crypto.SHA256, false},
+	{ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, emptyRawValue, ECDSA, crypto.SHA1, false},
+	{ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, emptyRawValue, ECDSA, crypto.SHA256, false},
+	{ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, emptyRawValue, ECDSA, crypto.SHA384, false},
+	{ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, emptyRawValue, ECDSA, crypto.SHA512, false},
+	{PureEd25519, "Ed25519", oidSignatureEd25519, emptyRawValue, Ed25519, crypto.Hash(0) /* no pre-hashing */, false},
+}
+
+var emptyRawValue = asn1.RawValue{}
+
+// DER encoded RSA PSS parameters for the
+// SHA256, SHA384, and SHA512 hashes as defined in RFC 3447, Appendix A.2.3.
+// The parameters contain the following values:
+//   - hashAlgorithm contains the associated hash identifier with NULL parameters
+//   - maskGenAlgorithm always contains the default mgf1SHA1 identifier
+//   - saltLength contains the length of the associated hash
+//   - trailerField always contains the default trailerFieldBC value
+var (
+	pssParametersSHA256 = asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 162, 3, 2, 1, 32}}
+	pssParametersSHA384 = asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 162, 3, 2, 1, 48}}
+	pssParametersSHA512 = asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 162, 3, 2, 1, 64}}
+)
+
+// pssParameters reflects the parameters in an AlgorithmIdentifier that
+// specifies RSA PSS. See RFC 3447, Appendix A.2.3.
+type pssParameters struct {
+	// The following three fields are not marked as
+	// optional because the default values specify SHA-1,
+	// which is no longer suitable for use in signatures.
+	Hash         pkix.AlgorithmIdentifier `asn1:"explicit,tag:0"`
+	MGF          pkix.AlgorithmIdentifier `asn1:"explicit,tag:1"`
+	SaltLength   int                      `asn1:"explicit,tag:2"`
+	TrailerField int                      `asn1:"optional,explicit,tag:3,default:1"`
+}
+
+func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) stdx509.SignatureAlgorithm {
+	if ai.Algorithm.Equal(oidSignatureEd25519) {
+		// RFC 8410, Section 3
+		// > For all of the OIDs, the parameters MUST be absent.
+		if len(ai.Parameters.FullBytes) != 0 {
+			return stdx509.UnknownSignatureAlgorithm
+		}
+	}
+
+	if !ai.Algorithm.Equal(oidSignatureRSAPSS) {
+		for _, details := range signatureAlgorithmDetails {
+			if ai.Algorithm.Equal(details.oid) {
+				return stdx509.SignatureAlgorithm(details.algo)
+			}
+		}
+		return stdx509.UnknownSignatureAlgorithm
+	}
+
+	// RSA PSS is special because it encodes important parameters
+	// in the Parameters.
+
+	var params pssParameters
+	if _, err := asn1.Unmarshal(ai.Parameters.FullBytes, &params); err != nil {
+		return stdx509.UnknownSignatureAlgorithm
+	}
+
+	var mgf1HashFunc pkix.AlgorithmIdentifier
+	if _, err := asn1.Unmarshal(params.MGF.Parameters.FullBytes, &mgf1HashFunc); err != nil {
+		return stdx509.UnknownSignatureAlgorithm
+	}
+
+	// PSS is greatly overburdened with options. This code forces them into
+	// three buckets by requiring that the MGF1 hash function always match the
+	// message hash function (as recommended in RFC 3447, Section 8.1), that the
+	// salt length matches the hash length, and that the trailer field has the
+	// default value.
+	if (len(params.Hash.Parameters.FullBytes) != 0 && !bytes.Equal(params.Hash.Parameters.FullBytes, asn1.NullBytes)) ||
+		!params.MGF.Algorithm.Equal(oidMGF1) ||
+		!mgf1HashFunc.Algorithm.Equal(params.Hash.Algorithm) ||
+		(len(mgf1HashFunc.Parameters.FullBytes) != 0 && !bytes.Equal(mgf1HashFunc.Parameters.FullBytes, asn1.NullBytes)) ||
+		params.TrailerField != 1 {
+		return stdx509.UnknownSignatureAlgorithm
+	}
+
+	switch {
+	case params.Hash.Algorithm.Equal(oidSHA256) && params.SaltLength == 32:
+		return stdx509.SHA256WithRSAPSS
+	case params.Hash.Algorithm.Equal(oidSHA384) && params.SaltLength == 48:
+		return stdx509.SHA384WithRSAPSS
+	case params.Hash.Algorithm.Equal(oidSHA512) && params.SaltLength == 64:
+		return stdx509.SHA512WithRSAPSS
+	}
+
+	return stdx509.UnknownSignatureAlgorithm
+}
+
+var (
+	// RFC 3279, 2.3 Public Key Algorithms
+	//
+	//	pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
+	//		rsadsi(113549) pkcs(1) 1 }
+	//
+	// rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 }
+	//
+	//	id-dsa OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
+	//		x9-57(10040) x9cm(4) 1 }
+	oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
+	oidPublicKeyDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1}
+	// RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters
+	//
+	//	id-ecPublicKey OBJECT IDENTIFIER ::= {
+	//		iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
+	oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
+	// RFC 8410, Section 3
+	//
+	//	id-X25519    OBJECT IDENTIFIER ::= { 1 3 101 110 }
+	//	id-Ed25519   OBJECT IDENTIFIER ::= { 1 3 101 112 }
+	oidPublicKeyX25519  = asn1.ObjectIdentifier{1, 3, 101, 110}
+	oidPublicKeyEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}
+)
+
+// getPublicKeyAlgorithmFromOID returns the exposed PublicKeyAlgorithm
+// identifier for public key types supported in certificates and CSRs. Marshal
+// and Parse functions may support a different set of public key types.
+func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) stdx509.PublicKeyAlgorithm {
+	switch {
+	case oid.Equal(oidPublicKeyRSA):
+		return stdx509.RSA
+	case oid.Equal(oidPublicKeyDSA):
+		return stdx509.DSA
+	case oid.Equal(oidPublicKeyECDSA):
+		return stdx509.ECDSA
+	case oid.Equal(oidPublicKeyEd25519):
+		return stdx509.Ed25519
+	}
+	return stdx509.UnknownPublicKeyAlgorithm
+}
+
+// RFC 5480, 2.1.1.1. Named Curve
+//
+//	secp224r1 OBJECT IDENTIFIER ::= {
+//	  iso(1) identified-organization(3) certicom(132) curve(0) 33 }
+//
+//	secp256r1 OBJECT IDENTIFIER ::= {
+//	  iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
+//	  prime(1) 7 }
+//
+//	secp384r1 OBJECT IDENTIFIER ::= {
+//	  iso(1) identified-organization(3) certicom(132) curve(0) 34 }
+//
+//	secp521r1 OBJECT IDENTIFIER ::= {
+//	  iso(1) identified-organization(3) certicom(132) curve(0) 35 }
+//
+// NB: secp256r1 is equivalent to prime256v1
+var (
+	oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}
+	oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
+	oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
+	oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
+)
+
+func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve {
+	switch {
+	case oid.Equal(oidNamedCurveP224):
+		return elliptic.P224()
+	case oid.Equal(oidNamedCurveP256):
+		return elliptic.P256()
+	case oid.Equal(oidNamedCurveP384):
+		return elliptic.P384()
+	case oid.Equal(oidNamedCurveP521):
+		return elliptic.P521()
+	}
+	return nil
+}
+
+// KeyUsage represents the set of actions that are valid for a given key. It's
+// a bitmap of the KeyUsage* constants.
+type KeyUsage int
+
+const (
+	KeyUsageDigitalSignature KeyUsage = 1 << iota
+	KeyUsageContentCommitment
+	KeyUsageKeyEncipherment
+	KeyUsageDataEncipherment
+	KeyUsageKeyAgreement
+	KeyUsageCertSign
+	KeyUsageCRLSign
+	KeyUsageEncipherOnly
+	KeyUsageDecipherOnly
+)
+
+// RFC 5280, 4.2.1.12  Extended Key Usage
+//
+//	anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }
+//
+//	id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
+//
+//	id-kp-serverAuth             OBJECT IDENTIFIER ::= { id-kp 1 }
+//	id-kp-clientAuth             OBJECT IDENTIFIER ::= { id-kp 2 }
+//	id-kp-codeSigning            OBJECT IDENTIFIER ::= { id-kp 3 }
+//	id-kp-emailProtection        OBJECT IDENTIFIER ::= { id-kp 4 }
+//	id-kp-timeStamping           OBJECT IDENTIFIER ::= { id-kp 8 }
+//	id-kp-OCSPSigning            OBJECT IDENTIFIER ::= { id-kp 9 }
+var (
+	oidExtKeyUsageAny                            = asn1.ObjectIdentifier{2, 5, 29, 37, 0}
+	oidExtKeyUsageServerAuth                     = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1}
+	oidExtKeyUsageClientAuth                     = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2}
+	oidExtKeyUsageCodeSigning                    = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3}
+	oidExtKeyUsageEmailProtection                = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4}
+	oidExtKeyUsageIPSECEndSystem                 = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 5}
+	oidExtKeyUsageIPSECTunnel                    = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 6}
+	oidExtKeyUsageIPSECUser                      = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 7}
+	oidExtKeyUsageTimeStamping                   = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8}
+	oidExtKeyUsageOCSPSigning                    = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9}
+	oidExtKeyUsageMicrosoftServerGatedCrypto     = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3}
+	oidExtKeyUsageNetscapeServerGatedCrypto      = asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 4, 1}
+	oidExtKeyUsageMicrosoftCommercialCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 22}
+	oidExtKeyUsageMicrosoftKernelCodeSigning     = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 61, 1, 1}
+)
+
+// ExtKeyUsage represents an extended set of actions that are valid for a given key.
+// Each of the ExtKeyUsage* constants define a unique action.
+type ExtKeyUsage int
+
+const (
+	ExtKeyUsageAny ExtKeyUsage = iota
+	ExtKeyUsageServerAuth
+	ExtKeyUsageClientAuth
+	ExtKeyUsageCodeSigning
+	ExtKeyUsageEmailProtection
+	ExtKeyUsageIPSECEndSystem
+	ExtKeyUsageIPSECTunnel
+	ExtKeyUsageIPSECUser
+	ExtKeyUsageTimeStamping
+	ExtKeyUsageOCSPSigning
+	ExtKeyUsageMicrosoftServerGatedCrypto
+	ExtKeyUsageNetscapeServerGatedCrypto
+	ExtKeyUsageMicrosoftCommercialCodeSigning
+	ExtKeyUsageMicrosoftKernelCodeSigning
+)
+
+// extKeyUsageOIDs contains the mapping between an ExtKeyUsage and its OID.
+var extKeyUsageOIDs = []struct {
+	extKeyUsage ExtKeyUsage
+	oid         asn1.ObjectIdentifier
+}{
+	{ExtKeyUsageAny, oidExtKeyUsageAny},
+	{ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth},
+	{ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth},
+	{ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning},
+	{ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection},
+	{ExtKeyUsageIPSECEndSystem, oidExtKeyUsageIPSECEndSystem},
+	{ExtKeyUsageIPSECTunnel, oidExtKeyUsageIPSECTunnel},
+	{ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser},
+	{ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping},
+	{ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning},
+	{ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto},
+	{ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto},
+	{ExtKeyUsageMicrosoftCommercialCodeSigning, oidExtKeyUsageMicrosoftCommercialCodeSigning},
+	{ExtKeyUsageMicrosoftKernelCodeSigning, oidExtKeyUsageMicrosoftKernelCodeSigning},
+}
+
+func extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku ExtKeyUsage, ok bool) {
+	for _, pair := range extKeyUsageOIDs {
+		if oid.Equal(pair.oid) {
+			return pair.extKeyUsage, true
+		}
+	}
+	return
+}
+
+const (
+	nameTypeEmail = 1
+	nameTypeDNS   = 2
+	nameTypeURI   = 6
+	nameTypeIP    = 7
+)
+
+var (
+	oidExtensionAuthorityInfoAccess = []int{1, 3, 6, 1, 5, 5, 7, 1, 1}
+)
+
+var (
+	oidAuthorityInfoAccessOcsp    = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1}
+	oidAuthorityInfoAccessIssuers = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2}
+)
+
+func isIA5String(s string) error {
+	for _, r := range s {
+		// Per RFC5280 "IA5String is limited to the set of ASCII characters"
+		if r > unicode.MaxASCII {
+			return fmt.Errorf("x509: %q cannot be encoded as an IA5String", s)
+		}
+	}
+
+	return nil
+}
diff --git a/vendor/go.mozilla.org/pkcs7/pkcs7.go b/vendor/github.com/smallstep/pkcs7/pkcs7.go
similarity index 70%
rename from vendor/go.mozilla.org/pkcs7/pkcs7.go
rename to vendor/github.com/smallstep/pkcs7/pkcs7.go
index ccc6cc6dfe..f6c6dfbbb5 100644
--- a/vendor/go.mozilla.org/pkcs7/pkcs7.go
+++ b/vendor/github.com/smallstep/pkcs7/pkcs7.go
@@ -13,8 +13,11 @@ import (
 	"errors"
 	"fmt"
 	"sort"
+	"sync"
 
 	_ "crypto/sha1" // for crypto.SHA1
+
+	legacyx509 "github.com/smallstep/pkcs7/internal/legacy/x509"
 )
 
 // PKCS7 Represents a PKCS7 structure
@@ -31,7 +34,7 @@ type contentInfo struct {
 	Content     asn1.RawValue `asn1:"explicit,optional,tag:0"`
 }
 
-// ErrUnsupportedContentType is returned when a PKCS7 content is not supported.
+// ErrUnsupportedContentType is returned when a PKCS7 content type is not supported.
 // Currently only Data (1.2.840.113549.1.7.1), Signed Data (1.2.840.113549.1.7.2),
 // and Enveloped Data are supported (1.2.840.113549.1.7.3)
 var ErrUnsupportedContentType = errors.New("pkcs7: cannot parse data: unimplemented content type")
@@ -53,6 +56,7 @@ var (
 	OIDDigestAlgorithmSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}
 	OIDDigestAlgorithmSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2}
 	OIDDigestAlgorithmSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3}
+	OIDDigestAlgorithmSHA224 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 4}
 
 	OIDDigestAlgorithmDSA     = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1}
 	OIDDigestAlgorithmDSASHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
@@ -63,23 +67,28 @@ var (
 	OIDDigestAlgorithmECDSASHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}
 
 	// Signature Algorithms
-	OIDEncryptionAlgorithmRSA       = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
-	OIDEncryptionAlgorithmRSASHA1   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
-	OIDEncryptionAlgorithmRSASHA256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
-	OIDEncryptionAlgorithmRSASHA384 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
-	OIDEncryptionAlgorithmRSASHA512 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
+	OIDEncryptionAlgorithmRSAMD5    = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}  // see https://www.rfc-editor.org/rfc/rfc8017#appendix-A.2.4
+	OIDEncryptionAlgorithmRSASHA1   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}  // ditto
+	OIDEncryptionAlgorithmRSASHA256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11} // ditto
+	OIDEncryptionAlgorithmRSASHA384 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12} // ditto
+	OIDEncryptionAlgorithmRSASHA512 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13} // ditto
+	OIDEncryptionAlgorithmRSASHA224 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 14} // ditto
 
 	OIDEncryptionAlgorithmECDSAP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
 	OIDEncryptionAlgorithmECDSAP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
 	OIDEncryptionAlgorithmECDSAP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
 
-	// Encryption Algorithms
-	OIDEncryptionAlgorithmDESCBC     = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 7}
-	OIDEncryptionAlgorithmDESEDE3CBC = asn1.ObjectIdentifier{1, 2, 840, 113549, 3, 7}
-	OIDEncryptionAlgorithmAES256CBC  = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 42}
-	OIDEncryptionAlgorithmAES128GCM  = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 6}
-	OIDEncryptionAlgorithmAES128CBC  = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 2}
-	OIDEncryptionAlgorithmAES256GCM  = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 46}
+	// Asymmetric Encryption Algorithms
+	OIDEncryptionAlgorithmRSA       = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} // see https://www.rfc-editor.org/rfc/rfc8017#appendix-A.2.2
+	OIDEncryptionAlgorithmRSAESOAEP = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 7} // see https://www.rfc-editor.org/rfc/rfc8017#appendix-A.2.1
+
+	// Symmetric Encryption Algorithms
+	OIDEncryptionAlgorithmDESCBC     = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 7}               // see https://www.rfc-editor.org/rfc/rfc8018.html#appendix-B.2.1
+	OIDEncryptionAlgorithmDESEDE3CBC = asn1.ObjectIdentifier{1, 2, 840, 113549, 3, 7}         // see https://www.rfc-editor.org/rfc/rfc8018.html#appendix-B.2.2
+	OIDEncryptionAlgorithmAES256CBC  = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 42} // see https://www.rfc-editor.org/rfc/rfc3565.html#section-4.1
+	OIDEncryptionAlgorithmAES128GCM  = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 6}  // see https://www.rfc-editor.org/rfc/rfc5084.html#section-3.2
+	OIDEncryptionAlgorithmAES128CBC  = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 2}  // see https://www.rfc-editor.org/rfc/rfc8018.html#appendix-B.2.5
+	OIDEncryptionAlgorithmAES256GCM  = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 46} // see https://www.rfc-editor.org/rfc/rfc5084.html#section-3.2
 )
 
 func getHashForOID(oid asn1.ObjectIdentifier) (crypto.Hash, error) {
@@ -114,11 +123,11 @@ func getDigestOIDForSignatureAlgorithm(digestAlg x509.SignatureAlgorithm) (asn1.
 	return nil, fmt.Errorf("pkcs7: cannot convert hash to oid, unknown hash algorithm")
 }
 
-// getOIDForEncryptionAlgorithm takes the private key type of the signer and
+// getOIDForEncryptionAlgorithm takes the public or private key type of the signer and
 // the OID of a digest algorithm to return the appropriate signerInfo.DigestEncryptionAlgorithm
-func getOIDForEncryptionAlgorithm(pkey crypto.PrivateKey, OIDDigestAlg asn1.ObjectIdentifier) (asn1.ObjectIdentifier, error) {
-	switch pkey.(type) {
-	case *rsa.PrivateKey:
+func getOIDForEncryptionAlgorithm(pkey interface{}, OIDDigestAlg asn1.ObjectIdentifier) (asn1.ObjectIdentifier, error) {
+	switch k := pkey.(type) {
+	case *rsa.PrivateKey, *rsa.PublicKey:
 		switch {
 		default:
 			return OIDEncryptionAlgorithmRSA, nil
@@ -133,7 +142,7 @@ func getOIDForEncryptionAlgorithm(pkey crypto.PrivateKey, OIDDigestAlg asn1.Obje
 		case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA512):
 			return OIDEncryptionAlgorithmRSASHA512, nil
 		}
-	case *ecdsa.PrivateKey:
+	case *ecdsa.PrivateKey, *ecdsa.PublicKey:
 		switch {
 		case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA1):
 			return OIDDigestAlgorithmECDSASHA1, nil
@@ -144,8 +153,13 @@ func getOIDForEncryptionAlgorithm(pkey crypto.PrivateKey, OIDDigestAlg asn1.Obje
 		case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA512):
 			return OIDDigestAlgorithmECDSASHA512, nil
 		}
-	case *dsa.PrivateKey:
+	case *dsa.PrivateKey, *dsa.PublicKey:
 		return OIDDigestAlgorithmDSA, nil
+	case crypto.Signer:
+		// This generic case is here to cover types from other packages. It
+		// was specifically added to handle the private keyRSA type in the
+		// github.com/go-piv/piv-go/piv package.
+		return getOIDForEncryptionAlgorithm(k.Public(), OIDDigestAlg)
 	}
 	return nil, fmt.Errorf("pkcs7: cannot convert encryption algorithm to oid, unknown private key type %T", pkey)
 
@@ -202,6 +216,40 @@ func parseEncryptedData(data []byte) (*PKCS7, error) {
 	}, nil
 }
 
+// SetFallbackLegacyX509CertificateParserEnabled enables parsing certificates
+// embedded in a PKCS7 message using the logic from crypto/x509 from before
+// Go 1.23. Go 1.23 introduced a breaking change in case a certificate contains
+// a critical authority key identifier, which is the correct thing to do based
+// on RFC 5280, but it breaks Windows devices performing the Simple Certificate
+// Enrolment Protocol (SCEP), as the certificates embedded in those requests
+// apparently have authority key identifier extensions marked critical.
+//
+// See https://go-review.googlesource.com/c/go/+/562341 for the change in the
+// Go source.
+//
+// When [SetFallbackLegacyX509CertificateParserEnabled] is called with true, it
+// enables parsing using the legacy crypto/x509 certificate parser. It'll first
+// try to parse the certificates using the regular Go crypto/x509 package, but
+// if it fails on the above case, it'll retry parsing the certificates using a
+// copy of the crypto/x509 package based on Go 1.23, but skips checking the
+// authority key identifier extension being critical or not.
+func SetFallbackLegacyX509CertificateParserEnabled(v bool) {
+	legacyX509CertificateParser.Lock()
+	legacyX509CertificateParser.enabled = v
+	legacyX509CertificateParser.Unlock()
+}
+
+var legacyX509CertificateParser struct {
+	sync.RWMutex
+	enabled bool
+}
+
+func isLegacyX509ParserEnabled() bool {
+	legacyX509CertificateParser.RLock()
+	defer legacyX509CertificateParser.RUnlock()
+	return legacyX509CertificateParser.enabled
+}
+
 func (raw rawCertificates) Parse() ([]*x509.Certificate, error) {
 	if len(raw.Raw) == 0 {
 		return nil, nil
@@ -212,7 +260,14 @@ func (raw rawCertificates) Parse() ([]*x509.Certificate, error) {
 		return nil, err
 	}
 
-	return x509.ParseCertificates(val.Bytes)
+	certificates, err := x509.ParseCertificates(val.Bytes)
+	if err != nil && err.Error() == "x509: authority key identifier incorrectly marked critical" {
+		if isLegacyX509ParserEnabled() {
+			certificates, err = legacyx509.ParseCertificates(val.Bytes)
+		}
+	}
+
+	return certificates, err
 }
 
 func isCertMatchForIssuerAndSerial(cert *x509.Certificate, ias issuerAndSerial) bool {
diff --git a/vendor/go.mozilla.org/pkcs7/sign.go b/vendor/github.com/smallstep/pkcs7/sign.go
similarity index 100%
rename from vendor/go.mozilla.org/pkcs7/sign.go
rename to vendor/github.com/smallstep/pkcs7/sign.go
diff --git a/vendor/go.mozilla.org/pkcs7/verify.go b/vendor/github.com/smallstep/pkcs7/verify.go
similarity index 87%
rename from vendor/go.mozilla.org/pkcs7/verify.go
rename to vendor/github.com/smallstep/pkcs7/verify.go
index f09e27245c..7525f918b1 100644
--- a/vendor/go.mozilla.org/pkcs7/verify.go
+++ b/vendor/github.com/smallstep/pkcs7/verify.go
@@ -54,6 +54,21 @@ func (p7 *PKCS7) VerifyWithChainAtTime(truststore *x509.CertPool, currentTime ti
 	return nil
 }
 
+// SigningTimeNotValidError is returned when the signing time attribute
+// falls outside of the signer certificate validity.
+type SigningTimeNotValidError struct {
+	SigningTime time.Time
+	NotBefore   time.Time // NotBefore of signer
+	NotAfter    time.Time // NotAfter of signer
+}
+
+func (e *SigningTimeNotValidError) Error() string {
+	return fmt.Sprintf("pkcs7: signing time %q is outside of certificate validity %q to %q",
+		e.SigningTime.Format(time.RFC3339),
+		e.NotBefore.Format(time.RFC3339),
+		e.NotAfter.Format(time.RFC3339))
+}
+
 func verifySignatureAtTime(p7 *PKCS7, signer signerInfo, truststore *x509.CertPool, currentTime time.Time) (err error) {
 	signedData := p7.Content
 	ee := getCertFromCertsByIssuerAndSerial(p7.Certificates, signer.IssuerAndSerialNumber)
@@ -91,10 +106,11 @@ func verifySignatureAtTime(p7 *PKCS7, signer signerInfo, truststore *x509.CertPo
 		if err == nil {
 			// signing time found, performing validity check
 			if signingTime.After(ee.NotAfter) || signingTime.Before(ee.NotBefore) {
-				return fmt.Errorf("pkcs7: signing time %q is outside of certificate validity %q to %q",
-					signingTime.Format(time.RFC3339),
-					ee.NotBefore.Format(time.RFC3339),
-					ee.NotAfter.Format(time.RFC3339))
+				return &SigningTimeNotValidError{
+					SigningTime: signingTime,
+					NotBefore:   ee.NotBefore,
+					NotAfter:    ee.NotAfter,
+				}
 			}
 		}
 	}
@@ -146,10 +162,11 @@ func verifySignature(p7 *PKCS7, signer signerInfo, truststore *x509.CertPool) (e
 		if err == nil {
 			// signing time found, performing validity check
 			if signingTime.After(ee.NotAfter) || signingTime.Before(ee.NotBefore) {
-				return fmt.Errorf("pkcs7: signing time %q is outside of certificate validity %q to %q",
-					signingTime.Format(time.RFC3339),
-					ee.NotBefore.Format(time.RFC3339),
-					ee.NotAfter.Format(time.RFC3339))
+				return &SigningTimeNotValidError{
+					SigningTime: signingTime,
+					NotBefore:   ee.NotBefore,
+					NotAfter:    ee.NotAfter,
+				}
 			}
 		}
 	}
@@ -210,8 +227,13 @@ func parseSignedData(data []byte) (*PKCS7, error) {
 	// Compound octet string
 	if compound.IsCompound {
 		if compound.Tag == 4 {
-			if _, err = asn1.Unmarshal(compound.Bytes, &content); err != nil {
-				return nil, err
+			for len(compound.Bytes) > 0 {
+				var cdata asn1.RawValue
+				if _, err = asn1.Unmarshal(compound.Bytes, &cdata); err != nil {
+					return nil, err
+				}
+				content = append(content, cdata.Bytes...)
+				compound.Bytes = compound.Bytes[len(cdata.FullBytes):]
 			}
 		} else {
 			content = compound.Bytes
@@ -278,13 +300,13 @@ func getSignatureAlgorithm(digestEncryption, digest pkix.AlgorithmIdentifier) (x
 		digestEncryption.Algorithm.Equal(OIDEncryptionAlgorithmRSASHA384),
 		digestEncryption.Algorithm.Equal(OIDEncryptionAlgorithmRSASHA512):
 		switch {
-		case digest.Algorithm.Equal(OIDDigestAlgorithmSHA1):
+		case digest.Algorithm.Equal(OIDDigestAlgorithmSHA1), digest.Algorithm.Equal(OIDEncryptionAlgorithmRSASHA1):
 			return x509.SHA1WithRSA, nil
-		case digest.Algorithm.Equal(OIDDigestAlgorithmSHA256):
+		case digest.Algorithm.Equal(OIDDigestAlgorithmSHA256), digest.Algorithm.Equal(OIDEncryptionAlgorithmRSASHA256):
 			return x509.SHA256WithRSA, nil
-		case digest.Algorithm.Equal(OIDDigestAlgorithmSHA384):
+		case digest.Algorithm.Equal(OIDDigestAlgorithmSHA384), digest.Algorithm.Equal(OIDEncryptionAlgorithmRSASHA384):
 			return x509.SHA384WithRSA, nil
-		case digest.Algorithm.Equal(OIDDigestAlgorithmSHA512):
+		case digest.Algorithm.Equal(OIDDigestAlgorithmSHA512), digest.Algorithm.Equal(OIDEncryptionAlgorithmRSASHA512):
 			return x509.SHA512WithRSA, nil
 		default:
 			return -1, fmt.Errorf("pkcs7: unsupported digest %q for encryption algorithm %q",
diff --git a/vendor/go.mozilla.org/pkcs7/README.md b/vendor/go.mozilla.org/pkcs7/README.md
deleted file mode 100644
index a55d117c68..0000000000
--- a/vendor/go.mozilla.org/pkcs7/README.md
+++ /dev/null
@@ -1,69 +0,0 @@
-# pkcs7
-
-[![GoDoc](https://godoc.org/go.mozilla.org/pkcs7?status.svg)](https://godoc.org/go.mozilla.org/pkcs7)
-[![Build Status](https://github.com/mozilla-services/pkcs7/workflows/CI/badge.svg?branch=master&event=push)](https://github.com/mozilla-services/pkcs7/actions/workflows/ci.yml?query=branch%3Amaster+event%3Apush)
-
-pkcs7 implements parsing and creating signed and enveloped messages.
-
-```go
-package main
-
-import (
-	"bytes"
-	"crypto/rsa"
-	"crypto/x509"
-	"encoding/pem"
-	"fmt"
-	"os"
-
-    "go.mozilla.org/pkcs7"
-)
-
-func SignAndDetach(content []byte, cert *x509.Certificate, privkey *rsa.PrivateKey) (signed []byte, err error) {
-	toBeSigned, err := NewSignedData(content)
-	if err != nil {
-		err = fmt.Errorf("Cannot initialize signed data: %s", err)
-		return
-	}
-	if err = toBeSigned.AddSigner(cert, privkey, SignerInfoConfig{}); err != nil {
-		err = fmt.Errorf("Cannot add signer: %s", err)
-		return
-	}
-
-	// Detach signature, omit if you want an embedded signature
-	toBeSigned.Detach()
-
-	signed, err = toBeSigned.Finish()
-	if err != nil {
-		err = fmt.Errorf("Cannot finish signing data: %s", err)
-		return
-	}
-
-	// Verify the signature
-	pem.Encode(os.Stdout, &pem.Block{Type: "PKCS7", Bytes: signed})
-	p7, err := pkcs7.Parse(signed)
-	if err != nil {
-		err = fmt.Errorf("Cannot parse our signed data: %s", err)
-		return
-	}
-
-	// since the signature was detached, reattach the content here
-	p7.Content = content
-
-	if bytes.Compare(content, p7.Content) != 0 {
-		err = fmt.Errorf("Our content was not in the parsed data:\n\tExpected: %s\n\tActual: %s", content, p7.Content)
-		return
-	}
-	if err = p7.Verify(); err != nil {
-		err = fmt.Errorf("Cannot verify our signed data: %s", err)
-		return
-	}
-
-	return signed, nil
-}
-```
-
-
-
-## Credits
-This is a fork of [fullsailor/pkcs7](https://github.com/fullsailor/pkcs7)
diff --git a/vendor/go.mozilla.org/pkcs7/verify_test_dsa.go b/vendor/go.mozilla.org/pkcs7/verify_test_dsa.go
deleted file mode 100644
index 1eb05bc3ea..0000000000
--- a/vendor/go.mozilla.org/pkcs7/verify_test_dsa.go
+++ /dev/null
@@ -1,182 +0,0 @@
-// +build go1.11 go1.12 go1.13 go1.14 go1.15
-
-package pkcs7
-
-import (
-	"crypto/x509"
-	"encoding/pem"
-	"fmt"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"testing"
-)
-
-func TestVerifyEC2(t *testing.T) {
-	fixture := UnmarshalDSATestFixture(EC2IdentityDocumentFixture)
-	p7, err := Parse(fixture.Input)
-	if err != nil {
-		t.Errorf("Parse encountered unexpected error: %v", err)
-	}
-	p7.Certificates = []*x509.Certificate{fixture.Certificate}
-	if err := p7.Verify(); err != nil {
-		t.Errorf("Verify failed with error: %v", err)
-	}
-}
-
-var EC2IdentityDocumentFixture = `
------BEGIN PKCS7-----
-MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA
-JIAEggGmewogICJwcml2YXRlSXAiIDogIjE3Mi4zMC4wLjI1MiIsCiAgImRldnBh
-eVByb2R1Y3RDb2RlcyIgOiBudWxsLAogICJhdmFpbGFiaWxpdHlab25lIiA6ICJ1
-cy1lYXN0LTFhIiwKICAidmVyc2lvbiIgOiAiMjAxMC0wOC0zMSIsCiAgImluc3Rh
-bmNlSWQiIDogImktZjc5ZmU1NmMiLAogICJiaWxsaW5nUHJvZHVjdHMiIDogbnVs
-bCwKICAiaW5zdGFuY2VUeXBlIiA6ICJ0Mi5taWNybyIsCiAgImFjY291bnRJZCIg
-OiAiMTIxNjU5MDE0MzM0IiwKICAiaW1hZ2VJZCIgOiAiYW1pLWZjZTNjNjk2IiwK
-ICAicGVuZGluZ1RpbWUiIDogIjIwMTYtMDQtMDhUMDM6MDE6MzhaIiwKICAiYXJj
-aGl0ZWN0dXJlIiA6ICJ4ODZfNjQiLAogICJrZXJuZWxJZCIgOiBudWxsLAogICJy
-YW1kaXNrSWQiIDogbnVsbCwKICAicmVnaW9uIiA6ICJ1cy1lYXN0LTEiCn0AAAAA
-AAAxggEYMIIBFAIBATBpMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5n
-dG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2Vi
-IFNlcnZpY2VzIExMQwIJAJa6SNnlXhpnMAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0B
-CQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNjA0MDgwMzAxNDRaMCMG
-CSqGSIb3DQEJBDEWBBTuUc28eBXmImAautC+wOjqcFCBVjAJBgcqhkjOOAQDBC8w
-LQIVAKA54NxGHWWCz5InboDmY/GHs33nAhQ6O/ZI86NwjA9Vz3RNMUJrUPU5tAAA
-AAAAAA==
------END PKCS7-----
------BEGIN CERTIFICATE-----
-MIIC7TCCAq0CCQCWukjZ5V4aZzAJBgcqhkjOOAQDMFwxCzAJBgNVBAYTAlVTMRkw
-FwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYD
-VQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAeFw0xMjAxMDUxMjU2MTJaFw0z
-ODAxMDUxMjU2MTJaMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9u
-IFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNl
-cnZpY2VzIExMQzCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQCjkvcS2bb1VQ4yt/5e
-ih5OO6kK/n1Lzllr7D8ZwtQP8fOEpp5E2ng+D6Ud1Z1gYipr58Kj3nssSNpI6bX3
-VyIQzK7wLclnd/YozqNNmgIyZecN7EglK9ITHJLP+x8FtUpt3QbyYXJdmVMegN6P
-hviYt5JH/nYl4hh3Pa1HJdskgQIVALVJ3ER11+Ko4tP6nwvHwh6+ERYRAoGBAI1j
-k+tkqMVHuAFcvAGKocTgsjJem6/5qomzJuKDmbJNu9Qxw3rAotXau8Qe+MBcJl/U
-hhy1KHVpCGl9fueQ2s6IL0CaO/buycU1CiYQk40KNHCcHfNiZbdlx1E9rpUp7bnF
-lRa2v1ntMX3caRVDdbtPEWmdxSCYsYFDk4mZrOLBA4GEAAKBgEbmeve5f8LIE/Gf
-MNmP9CM5eovQOGx5ho8WqD+aTebs+k2tn92BBPqeZqpWRa5P/+jrdKml1qx4llHW
-MXrs3IgIb6+hUIB+S8dz8/mmO0bpr76RoZVCXYab2CZedFut7qc3WUH9+EUAH5mw
-vSeDCOUMYQR7R9LINYwouHIziqQYMAkGByqGSM44BAMDLwAwLAIUWXBlk40xTwSw
-7HX32MxXYruse9ACFBNGmdX2ZBrVNGrN9N2f6ROk0k9K
------END CERTIFICATE-----`
-
-func TestDSASignWithOpenSSLAndVerify(t *testing.T) {
-	content := []byte(`
-A ship in port is safe,
-but that's not what ships are built for.
--- Grace Hopper`)
-	// write the content to a temp file
-	tmpContentFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_content")
-	if err != nil {
-		t.Fatal(err)
-	}
-	ioutil.WriteFile(tmpContentFile.Name(), content, 0755)
-
-	// write the signer cert to a temp file
-	tmpSignerCertFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_signer")
-	if err != nil {
-		t.Fatal(err)
-	}
-	ioutil.WriteFile(tmpSignerCertFile.Name(), dsaPublicCert, 0755)
-
-	// write the signer key to a temp file
-	tmpSignerKeyFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_key")
-	if err != nil {
-		t.Fatal(err)
-	}
-	ioutil.WriteFile(tmpSignerKeyFile.Name(), dsaPrivateKey, 0755)
-
-	tmpSignedFile, err := ioutil.TempFile("", "TestDSASignWithOpenSSLAndVerify_signature")
-	if err != nil {
-		t.Fatal(err)
-	}
-	// call openssl to sign the content
-	opensslCMD := exec.Command("openssl", "smime", "-sign", "-nodetach", "-md", "sha1",
-		"-in", tmpContentFile.Name(), "-out", tmpSignedFile.Name(),
-		"-signer", tmpSignerCertFile.Name(), "-inkey", tmpSignerKeyFile.Name(),
-		"-certfile", tmpSignerCertFile.Name(), "-outform", "PEM")
-	out, err := opensslCMD.CombinedOutput()
-	if err != nil {
-		t.Fatalf("openssl command failed with %s: %s", err, out)
-	}
-
-	// verify the signed content
-	pemSignature, err := ioutil.ReadFile(tmpSignedFile.Name())
-	if err != nil {
-		t.Fatal(err)
-	}
-	fmt.Printf("%s\n", pemSignature)
-	derBlock, _ := pem.Decode(pemSignature)
-	if derBlock == nil {
-		t.Fatalf("failed to read DER block from signature PEM %s", tmpSignedFile.Name())
-	}
-	p7, err := Parse(derBlock.Bytes)
-	if err != nil {
-		t.Fatalf("Parse encountered unexpected error: %v", err)
-	}
-	if err := p7.Verify(); err != nil {
-		t.Fatalf("Verify failed with error: %v", err)
-	}
-	os.Remove(tmpSignerCertFile.Name()) // clean up
-	os.Remove(tmpSignerKeyFile.Name())  // clean up
-	os.Remove(tmpContentFile.Name())    // clean up
-}
-
-var dsaPrivateKey = []byte(`-----BEGIN PRIVATE KEY-----
-MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdS
-PO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVCl
-pJ+f6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith
-1yrv8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7L
-vKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3
-zwkyjMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImo
-g9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoEFgIUfW4aPdQBn9gJZp2KuNpzgHzvfsE=
------END PRIVATE KEY-----`)
-
-var dsaPublicCert = []byte(`-----BEGIN CERTIFICATE-----
-MIIDOjCCAvWgAwIBAgIEPCY/UDANBglghkgBZQMEAwIFADBsMRAwDgYDVQQGEwdV
-bmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYD
-VQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRAwDgYDVQQDEwdVbmtub3du
-MB4XDTE4MTAyMjEzNDMwN1oXDTQ2MDMwOTEzNDMwN1owbDEQMA4GA1UEBhMHVW5r
-bm93bjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEQMA4GA1UE
-ChMHVW5rbm93bjEQMA4GA1UECxMHVW5rbm93bjEQMA4GA1UEAxMHVW5rbm93bjCC
-AbgwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADD
-Hj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gE
-exAiwk+7qdf+t8Yb+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/Ii
-Axmd0UgBxwIVAJdgUI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4
-V7l5lK+7+jrqgvlXTAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozI
-puE8FnqLVHyNKOCjrh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4Vrl
-nwaSi2ZegHtVJWQBTDv+z0kqA4GFAAKBgQDCriMPbEVBoRK4SOUeFwg7+VRf4TTp
-rcOQC9IVVoCjXzuWEGrp3ZI7YWJSpFnSch4lk29RH8O0HpI/NOzKnOBtnKr782pt
-1k/bJVMH9EaLd6MKnAVjrCDMYBB0MhebZ8QHY2elZZCWoqDYAcIDOsEx+m4NLErT
-ypPnjS5M0jm1PKMhMB8wHQYDVR0OBBYEFC0Yt5XdM0Kc95IX8NQ8XRssGPx7MA0G
-CWCGSAFlAwQDAgUAAzAAMC0CFQCIgQtrZZ9hdZG1ROhR5hc8nYEmbgIUAIlgC688
-qzy/7yePTlhlpj+ahMM=
------END CERTIFICATE-----`)
-
-type DSATestFixture struct {
-	Input       []byte
-	Certificate *x509.Certificate
-}
-
-func UnmarshalDSATestFixture(testPEMBlock string) DSATestFixture {
-	var result DSATestFixture
-	var derBlock *pem.Block
-	var pemBlock = []byte(testPEMBlock)
-	for {
-		derBlock, pemBlock = pem.Decode(pemBlock)
-		if derBlock == nil {
-			break
-		}
-		switch derBlock.Type {
-		case "PKCS7":
-			result.Input = derBlock.Bytes
-		case "CERTIFICATE":
-			result.Certificate, _ = x509.ParseCertificate(derBlock.Bytes)
-		}
-	}
-
-	return result
-}
diff --git a/vendor/golang.org/x/crypto/cryptobyte/asn1.go b/vendor/golang.org/x/crypto/cryptobyte/asn1.go
new file mode 100644
index 0000000000..2492f796af
--- /dev/null
+++ b/vendor/golang.org/x/crypto/cryptobyte/asn1.go
@@ -0,0 +1,825 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cryptobyte
+
+import (
+	encoding_asn1 "encoding/asn1"
+	"fmt"
+	"math/big"
+	"reflect"
+	"time"
+
+	"golang.org/x/crypto/cryptobyte/asn1"
+)
+
+// This file contains ASN.1-related methods for String and Builder.
+
+// Builder
+
+// AddASN1Int64 appends a DER-encoded ASN.1 INTEGER.
+func (b *Builder) AddASN1Int64(v int64) {
+	b.addASN1Signed(asn1.INTEGER, v)
+}
+
+// AddASN1Int64WithTag appends a DER-encoded ASN.1 INTEGER with the
+// given tag.
+func (b *Builder) AddASN1Int64WithTag(v int64, tag asn1.Tag) {
+	b.addASN1Signed(tag, v)
+}
+
+// AddASN1Enum appends a DER-encoded ASN.1 ENUMERATION.
+func (b *Builder) AddASN1Enum(v int64) {
+	b.addASN1Signed(asn1.ENUM, v)
+}
+
+func (b *Builder) addASN1Signed(tag asn1.Tag, v int64) {
+	b.AddASN1(tag, func(c *Builder) {
+		length := 1
+		for i := v; i >= 0x80 || i < -0x80; i >>= 8 {
+			length++
+		}
+
+		for ; length > 0; length-- {
+			i := v >> uint((length-1)*8) & 0xff
+			c.AddUint8(uint8(i))
+		}
+	})
+}
+
+// AddASN1Uint64 appends a DER-encoded ASN.1 INTEGER.
+func (b *Builder) AddASN1Uint64(v uint64) {
+	b.AddASN1(asn1.INTEGER, func(c *Builder) {
+		length := 1
+		for i := v; i >= 0x80; i >>= 8 {
+			length++
+		}
+
+		for ; length > 0; length-- {
+			i := v >> uint((length-1)*8) & 0xff
+			c.AddUint8(uint8(i))
+		}
+	})
+}
+
+// AddASN1BigInt appends a DER-encoded ASN.1 INTEGER.
+func (b *Builder) AddASN1BigInt(n *big.Int) {
+	if b.err != nil {
+		return
+	}
+
+	b.AddASN1(asn1.INTEGER, func(c *Builder) {
+		if n.Sign() < 0 {
+			// A negative number has to be converted to two's-complement form. So we
+			// invert and subtract 1. If the most-significant-bit isn't set then
+			// we'll need to pad the beginning with 0xff in order to keep the number
+			// negative.
+			nMinus1 := new(big.Int).Neg(n)
+			nMinus1.Sub(nMinus1, bigOne)
+			bytes := nMinus1.Bytes()
+			for i := range bytes {
+				bytes[i] ^= 0xff
+			}
+			if len(bytes) == 0 || bytes[0]&0x80 == 0 {
+				c.add(0xff)
+			}
+			c.add(bytes...)
+		} else if n.Sign() == 0 {
+			c.add(0)
+		} else {
+			bytes := n.Bytes()
+			if bytes[0]&0x80 != 0 {
+				c.add(0)
+			}
+			c.add(bytes...)
+		}
+	})
+}
+
+// AddASN1OctetString appends a DER-encoded ASN.1 OCTET STRING.
+func (b *Builder) AddASN1OctetString(bytes []byte) {
+	b.AddASN1(asn1.OCTET_STRING, func(c *Builder) {
+		c.AddBytes(bytes)
+	})
+}
+
+const generalizedTimeFormatStr = "20060102150405Z0700"
+
+// AddASN1GeneralizedTime appends a DER-encoded ASN.1 GENERALIZEDTIME.
+func (b *Builder) AddASN1GeneralizedTime(t time.Time) {
+	if t.Year() < 0 || t.Year() > 9999 {
+		b.err = fmt.Errorf("cryptobyte: cannot represent %v as a GeneralizedTime", t)
+		return
+	}
+	b.AddASN1(asn1.GeneralizedTime, func(c *Builder) {
+		c.AddBytes([]byte(t.Format(generalizedTimeFormatStr)))
+	})
+}
+
+// AddASN1UTCTime appends a DER-encoded ASN.1 UTCTime.
+func (b *Builder) AddASN1UTCTime(t time.Time) {
+	b.AddASN1(asn1.UTCTime, func(c *Builder) {
+		// As utilized by the X.509 profile, UTCTime can only
+		// represent the years 1950 through 2049.
+		if t.Year() < 1950 || t.Year() >= 2050 {
+			b.err = fmt.Errorf("cryptobyte: cannot represent %v as a UTCTime", t)
+			return
+		}
+		c.AddBytes([]byte(t.Format(defaultUTCTimeFormatStr)))
+	})
+}
+
+// AddASN1BitString appends a DER-encoded ASN.1 BIT STRING. This does not
+// support BIT STRINGs that are not a whole number of bytes.
+func (b *Builder) AddASN1BitString(data []byte) {
+	b.AddASN1(asn1.BIT_STRING, func(b *Builder) {
+		b.AddUint8(0)
+		b.AddBytes(data)
+	})
+}
+
+func (b *Builder) addBase128Int(n int64) {
+	var length int
+	if n == 0 {
+		length = 1
+	} else {
+		for i := n; i > 0; i >>= 7 {
+			length++
+		}
+	}
+
+	for i := length - 1; i >= 0; i-- {
+		o := byte(n >> uint(i*7))
+		o &= 0x7f
+		if i != 0 {
+			o |= 0x80
+		}
+
+		b.add(o)
+	}
+}
+
+func isValidOID(oid encoding_asn1.ObjectIdentifier) bool {
+	if len(oid) < 2 {
+		return false
+	}
+
+	if oid[0] > 2 || (oid[0] <= 1 && oid[1] >= 40) {
+		return false
+	}
+
+	for _, v := range oid {
+		if v < 0 {
+			return false
+		}
+	}
+
+	return true
+}
+
+func (b *Builder) AddASN1ObjectIdentifier(oid encoding_asn1.ObjectIdentifier) {
+	b.AddASN1(asn1.OBJECT_IDENTIFIER, func(b *Builder) {
+		if !isValidOID(oid) {
+			b.err = fmt.Errorf("cryptobyte: invalid OID: %v", oid)
+			return
+		}
+
+		b.addBase128Int(int64(oid[0])*40 + int64(oid[1]))
+		for _, v := range oid[2:] {
+			b.addBase128Int(int64(v))
+		}
+	})
+}
+
+func (b *Builder) AddASN1Boolean(v bool) {
+	b.AddASN1(asn1.BOOLEAN, func(b *Builder) {
+		if v {
+			b.AddUint8(0xff)
+		} else {
+			b.AddUint8(0)
+		}
+	})
+}
+
+func (b *Builder) AddASN1NULL() {
+	b.add(uint8(asn1.NULL), 0)
+}
+
+// MarshalASN1 calls encoding_asn1.Marshal on its input and appends the result if
+// successful or records an error if one occurred.
+func (b *Builder) MarshalASN1(v interface{}) {
+	// NOTE(martinkr): This is somewhat of a hack to allow propagation of
+	// encoding_asn1.Marshal errors into Builder.err. N.B. if you call MarshalASN1 with a
+	// value embedded into a struct, its tag information is lost.
+	if b.err != nil {
+		return
+	}
+	bytes, err := encoding_asn1.Marshal(v)
+	if err != nil {
+		b.err = err
+		return
+	}
+	b.AddBytes(bytes)
+}
+
+// AddASN1 appends an ASN.1 object. The object is prefixed with the given tag.
+// Tags greater than 30 are not supported and result in an error (i.e.
+// low-tag-number form only). The child builder passed to the
+// BuilderContinuation can be used to build the content of the ASN.1 object.
+func (b *Builder) AddASN1(tag asn1.Tag, f BuilderContinuation) {
+	if b.err != nil {
+		return
+	}
+	// Identifiers with the low five bits set indicate high-tag-number format
+	// (two or more octets), which we don't support.
+	if tag&0x1f == 0x1f {
+		b.err = fmt.Errorf("cryptobyte: high-tag number identifier octects not supported: 0x%x", tag)
+		return
+	}
+	b.AddUint8(uint8(tag))
+	b.addLengthPrefixed(1, true, f)
+}
+
+// String
+
+// ReadASN1Boolean decodes an ASN.1 BOOLEAN and converts it to a boolean
+// representation into out and advances. It reports whether the read
+// was successful.
+func (s *String) ReadASN1Boolean(out *bool) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.BOOLEAN) || len(bytes) != 1 {
+		return false
+	}
+
+	switch bytes[0] {
+	case 0:
+		*out = false
+	case 0xff:
+		*out = true
+	default:
+		return false
+	}
+
+	return true
+}
+
+// ReadASN1Integer decodes an ASN.1 INTEGER into out and advances. If out does
+// not point to an integer, to a big.Int, or to a []byte it panics. Only
+// positive and zero values can be decoded into []byte, and they are returned as
+// big-endian binary values that share memory with s. Positive values will have
+// no leading zeroes, and zero will be returned as a single zero byte.
+// ReadASN1Integer reports whether the read was successful.
+func (s *String) ReadASN1Integer(out interface{}) bool {
+	switch out := out.(type) {
+	case *int, *int8, *int16, *int32, *int64:
+		var i int64
+		if !s.readASN1Int64(&i) || reflect.ValueOf(out).Elem().OverflowInt(i) {
+			return false
+		}
+		reflect.ValueOf(out).Elem().SetInt(i)
+		return true
+	case *uint, *uint8, *uint16, *uint32, *uint64:
+		var u uint64
+		if !s.readASN1Uint64(&u) || reflect.ValueOf(out).Elem().OverflowUint(u) {
+			return false
+		}
+		reflect.ValueOf(out).Elem().SetUint(u)
+		return true
+	case *big.Int:
+		return s.readASN1BigInt(out)
+	case *[]byte:
+		return s.readASN1Bytes(out)
+	default:
+		panic("out does not point to an integer type")
+	}
+}
+
+func checkASN1Integer(bytes []byte) bool {
+	if len(bytes) == 0 {
+		// An INTEGER is encoded with at least one octet.
+		return false
+	}
+	if len(bytes) == 1 {
+		return true
+	}
+	if bytes[0] == 0 && bytes[1]&0x80 == 0 || bytes[0] == 0xff && bytes[1]&0x80 == 0x80 {
+		// Value is not minimally encoded.
+		return false
+	}
+	return true
+}
+
+var bigOne = big.NewInt(1)
+
+func (s *String) readASN1BigInt(out *big.Int) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) {
+		return false
+	}
+	if bytes[0]&0x80 == 0x80 {
+		// Negative number.
+		neg := make([]byte, len(bytes))
+		for i, b := range bytes {
+			neg[i] = ^b
+		}
+		out.SetBytes(neg)
+		out.Add(out, bigOne)
+		out.Neg(out)
+	} else {
+		out.SetBytes(bytes)
+	}
+	return true
+}
+
+func (s *String) readASN1Bytes(out *[]byte) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) {
+		return false
+	}
+	if bytes[0]&0x80 == 0x80 {
+		return false
+	}
+	for len(bytes) > 1 && bytes[0] == 0 {
+		bytes = bytes[1:]
+	}
+	*out = bytes
+	return true
+}
+
+func (s *String) readASN1Int64(out *int64) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Signed(out, bytes) {
+		return false
+	}
+	return true
+}
+
+func asn1Signed(out *int64, n []byte) bool {
+	length := len(n)
+	if length > 8 {
+		return false
+	}
+	for i := 0; i < length; i++ {
+		*out <<= 8
+		*out |= int64(n[i])
+	}
+	// Shift up and down in order to sign extend the result.
+	*out <<= 64 - uint8(length)*8
+	*out >>= 64 - uint8(length)*8
+	return true
+}
+
+func (s *String) readASN1Uint64(out *uint64) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Unsigned(out, bytes) {
+		return false
+	}
+	return true
+}
+
+func asn1Unsigned(out *uint64, n []byte) bool {
+	length := len(n)
+	if length > 9 || length == 9 && n[0] != 0 {
+		// Too large for uint64.
+		return false
+	}
+	if n[0]&0x80 != 0 {
+		// Negative number.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		*out <<= 8
+		*out |= uint64(n[i])
+	}
+	return true
+}
+
+// ReadASN1Int64WithTag decodes an ASN.1 INTEGER with the given tag into out
+// and advances. It reports whether the read was successful and resulted in a
+// value that can be represented in an int64.
+func (s *String) ReadASN1Int64WithTag(out *int64, tag asn1.Tag) bool {
+	var bytes String
+	return s.ReadASN1(&bytes, tag) && checkASN1Integer(bytes) && asn1Signed(out, bytes)
+}
+
+// ReadASN1Enum decodes an ASN.1 ENUMERATION into out and advances. It reports
+// whether the read was successful.
+func (s *String) ReadASN1Enum(out *int) bool {
+	var bytes String
+	var i int64
+	if !s.ReadASN1(&bytes, asn1.ENUM) || !checkASN1Integer(bytes) || !asn1Signed(&i, bytes) {
+		return false
+	}
+	if int64(int(i)) != i {
+		return false
+	}
+	*out = int(i)
+	return true
+}
+
+func (s *String) readBase128Int(out *int) bool {
+	ret := 0
+	for i := 0; len(*s) > 0; i++ {
+		if i == 5 {
+			return false
+		}
+		// Avoid overflowing int on a 32-bit platform.
+		// We don't want different behavior based on the architecture.
+		if ret >= 1<<(31-7) {
+			return false
+		}
+		ret <<= 7
+		b := s.read(1)[0]
+
+		// ITU-T X.690, section 8.19.2:
+		// The subidentifier shall be encoded in the fewest possible octets,
+		// that is, the leading octet of the subidentifier shall not have the value 0x80.
+		if i == 0 && b == 0x80 {
+			return false
+		}
+
+		ret |= int(b & 0x7f)
+		if b&0x80 == 0 {
+			*out = ret
+			return true
+		}
+	}
+	return false // truncated
+}
+
+// ReadASN1ObjectIdentifier decodes an ASN.1 OBJECT IDENTIFIER into out and
+// advances. It reports whether the read was successful.
+func (s *String) ReadASN1ObjectIdentifier(out *encoding_asn1.ObjectIdentifier) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.OBJECT_IDENTIFIER) || len(bytes) == 0 {
+		return false
+	}
+
+	// In the worst case, we get two elements from the first byte (which is
+	// encoded differently) and then every varint is a single byte long.
+	components := make([]int, len(bytes)+1)
+
+	// The first varint is 40*value1 + value2:
+	// According to this packing, value1 can take the values 0, 1 and 2 only.
+	// When value1 = 0 or value1 = 1, then value2 is <= 39. When value1 = 2,
+	// then there are no restrictions on value2.
+	var v int
+	if !bytes.readBase128Int(&v) {
+		return false
+	}
+	if v < 80 {
+		components[0] = v / 40
+		components[1] = v % 40
+	} else {
+		components[0] = 2
+		components[1] = v - 80
+	}
+
+	i := 2
+	for ; len(bytes) > 0; i++ {
+		if !bytes.readBase128Int(&v) {
+			return false
+		}
+		components[i] = v
+	}
+	*out = components[:i]
+	return true
+}
+
+// ReadASN1GeneralizedTime decodes an ASN.1 GENERALIZEDTIME into out and
+// advances. It reports whether the read was successful.
+func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.GeneralizedTime) {
+		return false
+	}
+	t := string(bytes)
+	res, err := time.Parse(generalizedTimeFormatStr, t)
+	if err != nil {
+		return false
+	}
+	if serialized := res.Format(generalizedTimeFormatStr); serialized != t {
+		return false
+	}
+	*out = res
+	return true
+}
+
+const defaultUTCTimeFormatStr = "060102150405Z0700"
+
+// ReadASN1UTCTime decodes an ASN.1 UTCTime into out and advances.
+// It reports whether the read was successful.
+func (s *String) ReadASN1UTCTime(out *time.Time) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.UTCTime) {
+		return false
+	}
+	t := string(bytes)
+
+	formatStr := defaultUTCTimeFormatStr
+	var err error
+	res, err := time.Parse(formatStr, t)
+	if err != nil {
+		// Fallback to minute precision if we can't parse second
+		// precision. If we are following X.509 or X.690 we shouldn't
+		// support this, but we do.
+		formatStr = "0601021504Z0700"
+		res, err = time.Parse(formatStr, t)
+	}
+	if err != nil {
+		return false
+	}
+
+	if serialized := res.Format(formatStr); serialized != t {
+		return false
+	}
+
+	if res.Year() >= 2050 {
+		// UTCTime interprets the low order digits 50-99 as 1950-99.
+		// This only applies to its use in the X.509 profile.
+		// See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
+		res = res.AddDate(-100, 0, 0)
+	}
+	*out = res
+	return true
+}
+
+// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances.
+// It reports whether the read was successful.
+func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 ||
+		len(bytes)*8/8 != len(bytes) {
+		return false
+	}
+
+	paddingBits := bytes[0]
+	bytes = bytes[1:]
+	if paddingBits > 7 ||
+		len(bytes) == 0 && paddingBits != 0 ||
+		len(bytes) > 0 && bytes[len(bytes)-1]&(1<<paddingBits-1) != 0 {
+		return false
+	}
+
+	out.BitLength = len(bytes)*8 - int(paddingBits)
+	out.Bytes = bytes
+	return true
+}
+
+// ReadASN1BitStringAsBytes decodes an ASN.1 BIT STRING into out and advances. It is
+// an error if the BIT STRING is not a whole number of bytes. It reports
+// whether the read was successful.
+func (s *String) ReadASN1BitStringAsBytes(out *[]byte) bool {
+	var bytes String
+	if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 {
+		return false
+	}
+
+	paddingBits := bytes[0]
+	if paddingBits != 0 {
+		return false
+	}
+	*out = bytes[1:]
+	return true
+}
+
+// ReadASN1Bytes reads the contents of a DER-encoded ASN.1 element (not including
+// tag and length bytes) into out, and advances. The element must match the
+// given tag. It reports whether the read was successful.
+func (s *String) ReadASN1Bytes(out *[]byte, tag asn1.Tag) bool {
+	return s.ReadASN1((*String)(out), tag)
+}
+
+// ReadASN1 reads the contents of a DER-encoded ASN.1 element (not including
+// tag and length bytes) into out, and advances. The element must match the
+// given tag. It reports whether the read was successful.
+//
+// Tags greater than 30 are not supported (i.e. low-tag-number format only).
+func (s *String) ReadASN1(out *String, tag asn1.Tag) bool {
+	var t asn1.Tag
+	if !s.ReadAnyASN1(out, &t) || t != tag {
+		return false
+	}
+	return true
+}
+
+// ReadASN1Element reads the contents of a DER-encoded ASN.1 element (including
+// tag and length bytes) into out, and advances. The element must match the
+// given tag. It reports whether the read was successful.
+//
+// Tags greater than 30 are not supported (i.e. low-tag-number format only).
+func (s *String) ReadASN1Element(out *String, tag asn1.Tag) bool {
+	var t asn1.Tag
+	if !s.ReadAnyASN1Element(out, &t) || t != tag {
+		return false
+	}
+	return true
+}
+
+// ReadAnyASN1 reads the contents of a DER-encoded ASN.1 element (not including
+// tag and length bytes) into out, sets outTag to its tag, and advances.
+// It reports whether the read was successful.
+//
+// Tags greater than 30 are not supported (i.e. low-tag-number format only).
+func (s *String) ReadAnyASN1(out *String, outTag *asn1.Tag) bool {
+	return s.readASN1(out, outTag, true /* skip header */)
+}
+
+// ReadAnyASN1Element reads the contents of a DER-encoded ASN.1 element
+// (including tag and length bytes) into out, sets outTag to is tag, and
+// advances. It reports whether the read was successful.
+//
+// Tags greater than 30 are not supported (i.e. low-tag-number format only).
+func (s *String) ReadAnyASN1Element(out *String, outTag *asn1.Tag) bool {
+	return s.readASN1(out, outTag, false /* include header */)
+}
+
+// PeekASN1Tag reports whether the next ASN.1 value on the string starts with
+// the given tag.
+func (s String) PeekASN1Tag(tag asn1.Tag) bool {
+	if len(s) == 0 {
+		return false
+	}
+	return asn1.Tag(s[0]) == tag
+}
+
+// SkipASN1 reads and discards an ASN.1 element with the given tag. It
+// reports whether the operation was successful.
+func (s *String) SkipASN1(tag asn1.Tag) bool {
+	var unused String
+	return s.ReadASN1(&unused, tag)
+}
+
+// ReadOptionalASN1 attempts to read the contents of a DER-encoded ASN.1
+// element (not including tag and length bytes) tagged with the given tag into
+// out. It stores whether an element with the tag was found in outPresent,
+// unless outPresent is nil. It reports whether the read was successful.
+func (s *String) ReadOptionalASN1(out *String, outPresent *bool, tag asn1.Tag) bool {
+	present := s.PeekASN1Tag(tag)
+	if outPresent != nil {
+		*outPresent = present
+	}
+	if present && !s.ReadASN1(out, tag) {
+		return false
+	}
+	return true
+}
+
+// SkipOptionalASN1 advances s over an ASN.1 element with the given tag, or
+// else leaves s unchanged. It reports whether the operation was successful.
+func (s *String) SkipOptionalASN1(tag asn1.Tag) bool {
+	if !s.PeekASN1Tag(tag) {
+		return true
+	}
+	var unused String
+	return s.ReadASN1(&unused, tag)
+}
+
+// ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER explicitly
+// tagged with tag into out and advances. If no element with a matching tag is
+// present, it writes defaultValue into out instead. Otherwise, it behaves like
+// ReadASN1Integer.
+func (s *String) ReadOptionalASN1Integer(out interface{}, tag asn1.Tag, defaultValue interface{}) bool {
+	var present bool
+	var i String
+	if !s.ReadOptionalASN1(&i, &present, tag) {
+		return false
+	}
+	if !present {
+		switch out.(type) {
+		case *int, *int8, *int16, *int32, *int64,
+			*uint, *uint8, *uint16, *uint32, *uint64, *[]byte:
+			reflect.ValueOf(out).Elem().Set(reflect.ValueOf(defaultValue))
+		case *big.Int:
+			if defaultValue, ok := defaultValue.(*big.Int); ok {
+				out.(*big.Int).Set(defaultValue)
+			} else {
+				panic("out points to big.Int, but defaultValue does not")
+			}
+		default:
+			panic("invalid integer type")
+		}
+		return true
+	}
+	if !i.ReadASN1Integer(out) || !i.Empty() {
+		return false
+	}
+	return true
+}
+
+// ReadOptionalASN1OctetString attempts to read an optional ASN.1 OCTET STRING
+// explicitly tagged with tag into out and advances. If no element with a
+// matching tag is present, it sets "out" to nil instead. It reports
+// whether the read was successful.
+func (s *String) ReadOptionalASN1OctetString(out *[]byte, outPresent *bool, tag asn1.Tag) bool {
+	var present bool
+	var child String
+	if !s.ReadOptionalASN1(&child, &present, tag) {
+		return false
+	}
+	if outPresent != nil {
+		*outPresent = present
+	}
+	if present {
+		var oct String
+		if !child.ReadASN1(&oct, asn1.OCTET_STRING) || !child.Empty() {
+			return false
+		}
+		*out = oct
+	} else {
+		*out = nil
+	}
+	return true
+}
+
+// ReadOptionalASN1Boolean attempts to read an optional ASN.1 BOOLEAN
+// explicitly tagged with tag into out and advances. If no element with a
+// matching tag is present, it sets "out" to defaultValue instead. It reports
+// whether the read was successful.
+func (s *String) ReadOptionalASN1Boolean(out *bool, tag asn1.Tag, defaultValue bool) bool {
+	var present bool
+	var child String
+	if !s.ReadOptionalASN1(&child, &present, tag) {
+		return false
+	}
+
+	if !present {
+		*out = defaultValue
+		return true
+	}
+
+	return child.ReadASN1Boolean(out)
+}
+
+func (s *String) readASN1(out *String, outTag *asn1.Tag, skipHeader bool) bool {
+	if len(*s) < 2 {
+		return false
+	}
+	tag, lenByte := (*s)[0], (*s)[1]
+
+	if tag&0x1f == 0x1f {
+		// ITU-T X.690 section 8.1.2
+		//
+		// An identifier octet with a tag part of 0x1f indicates a high-tag-number
+		// form identifier with two or more octets. We only support tags less than
+		// 31 (i.e. low-tag-number form, single octet identifier).
+		return false
+	}
+
+	if outTag != nil {
+		*outTag = asn1.Tag(tag)
+	}
+
+	// ITU-T X.690 section 8.1.3
+	//
+	// Bit 8 of the first length byte indicates whether the length is short- or
+	// long-form.
+	var length, headerLen uint32 // length includes headerLen
+	if lenByte&0x80 == 0 {
+		// Short-form length (section 8.1.3.4), encoded in bits 1-7.
+		length = uint32(lenByte) + 2
+		headerLen = 2
+	} else {
+		// Long-form length (section 8.1.3.5). Bits 1-7 encode the number of octets
+		// used to encode the length.
+		lenLen := lenByte & 0x7f
+		var len32 uint32
+
+		if lenLen == 0 || lenLen > 4 || len(*s) < int(2+lenLen) {
+			return false
+		}
+
+		lenBytes := String((*s)[2 : 2+lenLen])
+		if !lenBytes.readUnsigned(&len32, int(lenLen)) {
+			return false
+		}
+
+		// ITU-T X.690 section 10.1 (DER length forms) requires encoding the length
+		// with the minimum number of octets.
+		if len32 < 128 {
+			// Length should have used short-form encoding.
+			return false
+		}
+		if len32>>((lenLen-1)*8) == 0 {
+			// Leading octet is 0. Length should have been at least one byte shorter.
+			return false
+		}
+
+		headerLen = 2 + uint32(lenLen)
+		if headerLen+len32 < len32 {
+			// Overflow.
+			return false
+		}
+		length = headerLen + len32
+	}
+
+	if int(length) < 0 || !s.ReadBytes((*[]byte)(out), int(length)) {
+		return false
+	}
+	if skipHeader && !out.Skip(int(headerLen)) {
+		panic("cryptobyte: internal error")
+	}
+
+	return true
+}
diff --git a/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go b/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go
new file mode 100644
index 0000000000..90ef6a241d
--- /dev/null
+++ b/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go
@@ -0,0 +1,46 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package asn1 contains supporting types for parsing and building ASN.1
+// messages with the cryptobyte package.
+package asn1
+
+// Tag represents an ASN.1 identifier octet, consisting of a tag number
+// (indicating a type) and class (such as context-specific or constructed).
+//
+// Methods in the cryptobyte package only support the low-tag-number form, i.e.
+// a single identifier octet with bits 7-8 encoding the class and bits 1-6
+// encoding the tag number.
+type Tag uint8
+
+const (
+	classConstructed     = 0x20
+	classContextSpecific = 0x80
+)
+
+// Constructed returns t with the constructed class bit set.
+func (t Tag) Constructed() Tag { return t | classConstructed }
+
+// ContextSpecific returns t with the context-specific class bit set.
+func (t Tag) ContextSpecific() Tag { return t | classContextSpecific }
+
+// The following is a list of standard tag and class combinations.
+const (
+	BOOLEAN           = Tag(1)
+	INTEGER           = Tag(2)
+	BIT_STRING        = Tag(3)
+	OCTET_STRING      = Tag(4)
+	NULL              = Tag(5)
+	OBJECT_IDENTIFIER = Tag(6)
+	ENUM              = Tag(10)
+	UTF8String        = Tag(12)
+	SEQUENCE          = Tag(16 | classConstructed)
+	SET               = Tag(17 | classConstructed)
+	PrintableString   = Tag(19)
+	T61String         = Tag(20)
+	IA5String         = Tag(22)
+	UTCTime           = Tag(23)
+	GeneralizedTime   = Tag(24)
+	GeneralString     = Tag(27)
+)
diff --git a/vendor/golang.org/x/crypto/cryptobyte/builder.go b/vendor/golang.org/x/crypto/cryptobyte/builder.go
new file mode 100644
index 0000000000..cf254f5f1e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/cryptobyte/builder.go
@@ -0,0 +1,350 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cryptobyte
+
+import (
+	"errors"
+	"fmt"
+)
+
+// A Builder builds byte strings from fixed-length and length-prefixed values.
+// Builders either allocate space as needed, or are ‘fixed’, which means that
+// they write into a given buffer and produce an error if it's exhausted.
+//
+// The zero value is a usable Builder that allocates space as needed.
+//
+// Simple values are marshaled and appended to a Builder using methods on the
+// Builder. Length-prefixed values are marshaled by providing a
+// BuilderContinuation, which is a function that writes the inner contents of
+// the value to a given Builder. See the documentation for BuilderContinuation
+// for details.
+type Builder struct {
+	err            error
+	result         []byte
+	fixedSize      bool
+	child          *Builder
+	offset         int
+	pendingLenLen  int
+	pendingIsASN1  bool
+	inContinuation *bool
+}
+
+// NewBuilder creates a Builder that appends its output to the given buffer.
+// Like append(), the slice will be reallocated if its capacity is exceeded.
+// Use Bytes to get the final buffer.
+func NewBuilder(buffer []byte) *Builder {
+	return &Builder{
+		result: buffer,
+	}
+}
+
+// NewFixedBuilder creates a Builder that appends its output into the given
+// buffer. This builder does not reallocate the output buffer. Writes that
+// would exceed the buffer's capacity are treated as an error.
+func NewFixedBuilder(buffer []byte) *Builder {
+	return &Builder{
+		result:    buffer,
+		fixedSize: true,
+	}
+}
+
+// SetError sets the value to be returned as the error from Bytes. Writes
+// performed after calling SetError are ignored.
+func (b *Builder) SetError(err error) {
+	b.err = err
+}
+
+// Bytes returns the bytes written by the builder or an error if one has
+// occurred during building.
+func (b *Builder) Bytes() ([]byte, error) {
+	if b.err != nil {
+		return nil, b.err
+	}
+	return b.result[b.offset:], nil
+}
+
+// BytesOrPanic returns the bytes written by the builder or panics if an error
+// has occurred during building.
+func (b *Builder) BytesOrPanic() []byte {
+	if b.err != nil {
+		panic(b.err)
+	}
+	return b.result[b.offset:]
+}
+
+// AddUint8 appends an 8-bit value to the byte string.
+func (b *Builder) AddUint8(v uint8) {
+	b.add(byte(v))
+}
+
+// AddUint16 appends a big-endian, 16-bit value to the byte string.
+func (b *Builder) AddUint16(v uint16) {
+	b.add(byte(v>>8), byte(v))
+}
+
+// AddUint24 appends a big-endian, 24-bit value to the byte string. The highest
+// byte of the 32-bit input value is silently truncated.
+func (b *Builder) AddUint24(v uint32) {
+	b.add(byte(v>>16), byte(v>>8), byte(v))
+}
+
+// AddUint32 appends a big-endian, 32-bit value to the byte string.
+func (b *Builder) AddUint32(v uint32) {
+	b.add(byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
+}
+
+// AddUint48 appends a big-endian, 48-bit value to the byte string.
+func (b *Builder) AddUint48(v uint64) {
+	b.add(byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
+}
+
+// AddUint64 appends a big-endian, 64-bit value to the byte string.
+func (b *Builder) AddUint64(v uint64) {
+	b.add(byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
+}
+
+// AddBytes appends a sequence of bytes to the byte string.
+func (b *Builder) AddBytes(v []byte) {
+	b.add(v...)
+}
+
+// BuilderContinuation is a continuation-passing interface for building
+// length-prefixed byte sequences. Builder methods for length-prefixed
+// sequences (AddUint8LengthPrefixed etc) will invoke the BuilderContinuation
+// supplied to them. The child builder passed to the continuation can be used
+// to build the content of the length-prefixed sequence. For example:
+//
+//	parent := cryptobyte.NewBuilder()
+//	parent.AddUint8LengthPrefixed(func (child *Builder) {
+//	  child.AddUint8(42)
+//	  child.AddUint8LengthPrefixed(func (grandchild *Builder) {
+//	    grandchild.AddUint8(5)
+//	  })
+//	})
+//
+// It is an error to write more bytes to the child than allowed by the reserved
+// length prefix. After the continuation returns, the child must be considered
+// invalid, i.e. users must not store any copies or references of the child
+// that outlive the continuation.
+//
+// If the continuation panics with a value of type BuildError then the inner
+// error will be returned as the error from Bytes. If the child panics
+// otherwise then Bytes will repanic with the same value.
+type BuilderContinuation func(child *Builder)
+
+// BuildError wraps an error. If a BuilderContinuation panics with this value,
+// the panic will be recovered and the inner error will be returned from
+// Builder.Bytes.
+type BuildError struct {
+	Err error
+}
+
+// AddUint8LengthPrefixed adds a 8-bit length-prefixed byte sequence.
+func (b *Builder) AddUint8LengthPrefixed(f BuilderContinuation) {
+	b.addLengthPrefixed(1, false, f)
+}
+
+// AddUint16LengthPrefixed adds a big-endian, 16-bit length-prefixed byte sequence.
+func (b *Builder) AddUint16LengthPrefixed(f BuilderContinuation) {
+	b.addLengthPrefixed(2, false, f)
+}
+
+// AddUint24LengthPrefixed adds a big-endian, 24-bit length-prefixed byte sequence.
+func (b *Builder) AddUint24LengthPrefixed(f BuilderContinuation) {
+	b.addLengthPrefixed(3, false, f)
+}
+
+// AddUint32LengthPrefixed adds a big-endian, 32-bit length-prefixed byte sequence.
+func (b *Builder) AddUint32LengthPrefixed(f BuilderContinuation) {
+	b.addLengthPrefixed(4, false, f)
+}
+
+func (b *Builder) callContinuation(f BuilderContinuation, arg *Builder) {
+	if !*b.inContinuation {
+		*b.inContinuation = true
+
+		defer func() {
+			*b.inContinuation = false
+
+			r := recover()
+			if r == nil {
+				return
+			}
+
+			if buildError, ok := r.(BuildError); ok {
+				b.err = buildError.Err
+			} else {
+				panic(r)
+			}
+		}()
+	}
+
+	f(arg)
+}
+
+func (b *Builder) addLengthPrefixed(lenLen int, isASN1 bool, f BuilderContinuation) {
+	// Subsequent writes can be ignored if the builder has encountered an error.
+	if b.err != nil {
+		return
+	}
+
+	offset := len(b.result)
+	b.add(make([]byte, lenLen)...)
+
+	if b.inContinuation == nil {
+		b.inContinuation = new(bool)
+	}
+
+	b.child = &Builder{
+		result:         b.result,
+		fixedSize:      b.fixedSize,
+		offset:         offset,
+		pendingLenLen:  lenLen,
+		pendingIsASN1:  isASN1,
+		inContinuation: b.inContinuation,
+	}
+
+	b.callContinuation(f, b.child)
+	b.flushChild()
+	if b.child != nil {
+		panic("cryptobyte: internal error")
+	}
+}
+
+func (b *Builder) flushChild() {
+	if b.child == nil {
+		return
+	}
+	b.child.flushChild()
+	child := b.child
+	b.child = nil
+
+	if child.err != nil {
+		b.err = child.err
+		return
+	}
+
+	length := len(child.result) - child.pendingLenLen - child.offset
+
+	if length < 0 {
+		panic("cryptobyte: internal error") // result unexpectedly shrunk
+	}
+
+	if child.pendingIsASN1 {
+		// For ASN.1, we reserved a single byte for the length. If that turned out
+		// to be incorrect, we have to move the contents along in order to make
+		// space.
+		if child.pendingLenLen != 1 {
+			panic("cryptobyte: internal error")
+		}
+		var lenLen, lenByte uint8
+		if int64(length) > 0xfffffffe {
+			b.err = errors.New("pending ASN.1 child too long")
+			return
+		} else if length > 0xffffff {
+			lenLen = 5
+			lenByte = 0x80 | 4
+		} else if length > 0xffff {
+			lenLen = 4
+			lenByte = 0x80 | 3
+		} else if length > 0xff {
+			lenLen = 3
+			lenByte = 0x80 | 2
+		} else if length > 0x7f {
+			lenLen = 2
+			lenByte = 0x80 | 1
+		} else {
+			lenLen = 1
+			lenByte = uint8(length)
+			length = 0
+		}
+
+		// Insert the initial length byte, make space for successive length bytes,
+		// and adjust the offset.
+		child.result[child.offset] = lenByte
+		extraBytes := int(lenLen - 1)
+		if extraBytes != 0 {
+			child.add(make([]byte, extraBytes)...)
+			childStart := child.offset + child.pendingLenLen
+			copy(child.result[childStart+extraBytes:], child.result[childStart:])
+		}
+		child.offset++
+		child.pendingLenLen = extraBytes
+	}
+
+	l := length
+	for i := child.pendingLenLen - 1; i >= 0; i-- {
+		child.result[child.offset+i] = uint8(l)
+		l >>= 8
+	}
+	if l != 0 {
+		b.err = fmt.Errorf("cryptobyte: pending child length %d exceeds %d-byte length prefix", length, child.pendingLenLen)
+		return
+	}
+
+	if b.fixedSize && &b.result[0] != &child.result[0] {
+		panic("cryptobyte: BuilderContinuation reallocated a fixed-size buffer")
+	}
+
+	b.result = child.result
+}
+
+func (b *Builder) add(bytes ...byte) {
+	if b.err != nil {
+		return
+	}
+	if b.child != nil {
+		panic("cryptobyte: attempted write while child is pending")
+	}
+	if len(b.result)+len(bytes) < len(bytes) {
+		b.err = errors.New("cryptobyte: length overflow")
+	}
+	if b.fixedSize && len(b.result)+len(bytes) > cap(b.result) {
+		b.err = errors.New("cryptobyte: Builder is exceeding its fixed-size buffer")
+		return
+	}
+	b.result = append(b.result, bytes...)
+}
+
+// Unwrite rolls back non-negative n bytes written directly to the Builder.
+// An attempt by a child builder passed to a continuation to unwrite bytes
+// from its parent will panic.
+func (b *Builder) Unwrite(n int) {
+	if b.err != nil {
+		return
+	}
+	if b.child != nil {
+		panic("cryptobyte: attempted unwrite while child is pending")
+	}
+	length := len(b.result) - b.pendingLenLen - b.offset
+	if length < 0 {
+		panic("cryptobyte: internal error")
+	}
+	if n < 0 {
+		panic("cryptobyte: attempted to unwrite negative number of bytes")
+	}
+	if n > length {
+		panic("cryptobyte: attempted to unwrite more than was written")
+	}
+	b.result = b.result[:len(b.result)-n]
+}
+
+// A MarshalingValue marshals itself into a Builder.
+type MarshalingValue interface {
+	// Marshal is called by Builder.AddValue. It receives a pointer to a builder
+	// to marshal itself into. It may return an error that occurred during
+	// marshaling, such as unset or invalid values.
+	Marshal(b *Builder) error
+}
+
+// AddValue calls Marshal on v, passing a pointer to the builder to append to.
+// If Marshal returns an error, it is set on the Builder so that subsequent
+// appends don't have an effect.
+func (b *Builder) AddValue(v MarshalingValue) {
+	err := v.Marshal(b)
+	if err != nil {
+		b.err = err
+	}
+}
diff --git a/vendor/golang.org/x/crypto/cryptobyte/string.go b/vendor/golang.org/x/crypto/cryptobyte/string.go
new file mode 100644
index 0000000000..4b0f8097f9
--- /dev/null
+++ b/vendor/golang.org/x/crypto/cryptobyte/string.go
@@ -0,0 +1,183 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package cryptobyte contains types that help with parsing and constructing
+// length-prefixed, binary messages, including ASN.1 DER. (The asn1 subpackage
+// contains useful ASN.1 constants.)
+//
+// The String type is for parsing. It wraps a []byte slice and provides helper
+// functions for consuming structures, value by value.
+//
+// The Builder type is for constructing messages. It providers helper functions
+// for appending values and also for appending length-prefixed submessages –
+// without having to worry about calculating the length prefix ahead of time.
+//
+// See the documentation and examples for the Builder and String types to get
+// started.
+package cryptobyte
+
+// String represents a string of bytes. It provides methods for parsing
+// fixed-length and length-prefixed values from it.
+type String []byte
+
+// read advances a String by n bytes and returns them. If less than n bytes
+// remain, it returns nil.
+func (s *String) read(n int) []byte {
+	if len(*s) < n || n < 0 {
+		return nil
+	}
+	v := (*s)[:n]
+	*s = (*s)[n:]
+	return v
+}
+
+// Skip advances the String by n byte and reports whether it was successful.
+func (s *String) Skip(n int) bool {
+	return s.read(n) != nil
+}
+
+// ReadUint8 decodes an 8-bit value into out and advances over it.
+// It reports whether the read was successful.
+func (s *String) ReadUint8(out *uint8) bool {
+	v := s.read(1)
+	if v == nil {
+		return false
+	}
+	*out = uint8(v[0])
+	return true
+}
+
+// ReadUint16 decodes a big-endian, 16-bit value into out and advances over it.
+// It reports whether the read was successful.
+func (s *String) ReadUint16(out *uint16) bool {
+	v := s.read(2)
+	if v == nil {
+		return false
+	}
+	*out = uint16(v[0])<<8 | uint16(v[1])
+	return true
+}
+
+// ReadUint24 decodes a big-endian, 24-bit value into out and advances over it.
+// It reports whether the read was successful.
+func (s *String) ReadUint24(out *uint32) bool {
+	v := s.read(3)
+	if v == nil {
+		return false
+	}
+	*out = uint32(v[0])<<16 | uint32(v[1])<<8 | uint32(v[2])
+	return true
+}
+
+// ReadUint32 decodes a big-endian, 32-bit value into out and advances over it.
+// It reports whether the read was successful.
+func (s *String) ReadUint32(out *uint32) bool {
+	v := s.read(4)
+	if v == nil {
+		return false
+	}
+	*out = uint32(v[0])<<24 | uint32(v[1])<<16 | uint32(v[2])<<8 | uint32(v[3])
+	return true
+}
+
+// ReadUint48 decodes a big-endian, 48-bit value into out and advances over it.
+// It reports whether the read was successful.
+func (s *String) ReadUint48(out *uint64) bool {
+	v := s.read(6)
+	if v == nil {
+		return false
+	}
+	*out = uint64(v[0])<<40 | uint64(v[1])<<32 | uint64(v[2])<<24 | uint64(v[3])<<16 | uint64(v[4])<<8 | uint64(v[5])
+	return true
+}
+
+// ReadUint64 decodes a big-endian, 64-bit value into out and advances over it.
+// It reports whether the read was successful.
+func (s *String) ReadUint64(out *uint64) bool {
+	v := s.read(8)
+	if v == nil {
+		return false
+	}
+	*out = uint64(v[0])<<56 | uint64(v[1])<<48 | uint64(v[2])<<40 | uint64(v[3])<<32 | uint64(v[4])<<24 | uint64(v[5])<<16 | uint64(v[6])<<8 | uint64(v[7])
+	return true
+}
+
+func (s *String) readUnsigned(out *uint32, length int) bool {
+	v := s.read(length)
+	if v == nil {
+		return false
+	}
+	var result uint32
+	for i := 0; i < length; i++ {
+		result <<= 8
+		result |= uint32(v[i])
+	}
+	*out = result
+	return true
+}
+
+func (s *String) readLengthPrefixed(lenLen int, outChild *String) bool {
+	lenBytes := s.read(lenLen)
+	if lenBytes == nil {
+		return false
+	}
+	var length uint32
+	for _, b := range lenBytes {
+		length = length << 8
+		length = length | uint32(b)
+	}
+	v := s.read(int(length))
+	if v == nil {
+		return false
+	}
+	*outChild = v
+	return true
+}
+
+// ReadUint8LengthPrefixed reads the content of an 8-bit length-prefixed value
+// into out and advances over it. It reports whether the read was successful.
+func (s *String) ReadUint8LengthPrefixed(out *String) bool {
+	return s.readLengthPrefixed(1, out)
+}
+
+// ReadUint16LengthPrefixed reads the content of a big-endian, 16-bit
+// length-prefixed value into out and advances over it. It reports whether the
+// read was successful.
+func (s *String) ReadUint16LengthPrefixed(out *String) bool {
+	return s.readLengthPrefixed(2, out)
+}
+
+// ReadUint24LengthPrefixed reads the content of a big-endian, 24-bit
+// length-prefixed value into out and advances over it. It reports whether
+// the read was successful.
+func (s *String) ReadUint24LengthPrefixed(out *String) bool {
+	return s.readLengthPrefixed(3, out)
+}
+
+// ReadBytes reads n bytes into out and advances over them. It reports
+// whether the read was successful.
+func (s *String) ReadBytes(out *[]byte, n int) bool {
+	v := s.read(n)
+	if v == nil {
+		return false
+	}
+	*out = v
+	return true
+}
+
+// CopyBytes copies len(out) bytes into out and advances over them. It reports
+// whether the copy operation was successful
+func (s *String) CopyBytes(out []byte) bool {
+	n := len(out)
+	v := s.read(n)
+	if v == nil {
+		return false
+	}
+	return copy(out, v) == n
+}
+
+// Empty reports whether the string does not contain any bytes.
+func (s String) Empty() bool {
+	return len(s) == 0
+}
diff --git a/vendor/google.golang.org/grpc/CONTRIBUTING.md b/vendor/google.golang.org/grpc/CONTRIBUTING.md
index 0854d298e4..d9bfa6e1e7 100644
--- a/vendor/google.golang.org/grpc/CONTRIBUTING.md
+++ b/vendor/google.golang.org/grpc/CONTRIBUTING.md
@@ -4,7 +4,7 @@ We definitely welcome your patches and contributions to gRPC! Please read the gR
 organization's [governance rules](https://github.com/grpc/grpc-community/blob/master/governance.md)
 and [contribution guidelines](https://github.com/grpc/grpc-community/blob/master/CONTRIBUTING.md) before proceeding.
 
-If you are new to github, please start by reading [Pull Request howto](https://help.github.com/articles/about-pull-requests/)
+If you are new to GitHub, please start by reading [Pull Request howto](https://help.github.com/articles/about-pull-requests/)
 
 ## Legal requirements
 
@@ -25,8 +25,8 @@ How to get your contributions merged smoothly and quickly.
   is a great place to start. These issues are well-documented and usually can be
   resolved with a single pull request.
 
-- If you are adding a new file, make sure it has the copyright message template 
-  at the top as a comment. You can copy over the message from an existing file 
+- If you are adding a new file, make sure it has the copyright message template
+  at the top as a comment. You can copy over the message from an existing file
   and update the year.
 
 - The grpc package should only depend on standard Go packages and a small number
@@ -39,12 +39,12 @@ How to get your contributions merged smoothly and quickly.
   proposal](https://github.com/grpc/proposal).
 
 - Provide a good **PR description** as a record of **what** change is being made
-  and **why** it was made. Link to a github issue if it exists.
+  and **why** it was made. Link to a GitHub issue if it exists.
 
-- If you want to fix formatting or style, consider whether your changes are an 
-  obvious improvement or might be considered a personal preference. If a style 
-  change is based on preference, it likely will not be accepted. If it corrects 
-  widely agreed-upon anti-patterns, then please do create a PR and explain the 
+- If you want to fix formatting or style, consider whether your changes are an
+  obvious improvement or might be considered a personal preference. If a style
+  change is based on preference, it likely will not be accepted. If it corrects
+  widely agreed-upon anti-patterns, then please do create a PR and explain the
   benefits of the change.
 
 - Unless your PR is trivial, you should expect there will be reviewer comments
diff --git a/vendor/google.golang.org/grpc/balancer/balancer.go b/vendor/google.golang.org/grpc/balancer/balancer.go
index b181f386a1..3a2092f105 100644
--- a/vendor/google.golang.org/grpc/balancer/balancer.go
+++ b/vendor/google.golang.org/grpc/balancer/balancer.go
@@ -130,7 +130,7 @@ type SubConn interface {
 	// UpdateAddresses updates the addresses used in this SubConn.
 	// gRPC checks if currently-connected address is still in the new list.
 	// If it's in the list, the connection will be kept.
-	// If it's not in the list, the connection will gracefully closed, and
+	// If it's not in the list, the connection will gracefully close, and
 	// a new connection will be created.
 	//
 	// This will trigger a state transition for the SubConn.
@@ -142,8 +142,11 @@ type SubConn interface {
 	Connect()
 	// GetOrBuildProducer returns a reference to the existing Producer for this
 	// ProducerBuilder in this SubConn, or, if one does not currently exist,
-	// creates a new one and returns it.  Returns a close function which must
-	// be called when the Producer is no longer needed.
+	// creates a new one and returns it.  Returns a close function which may be
+	// called when the Producer is no longer needed.  Otherwise the producer
+	// will automatically be closed upon connection loss or subchannel close.
+	// Should only be called on a SubConn in state Ready.  Otherwise the
+	// producer will be unable to create streams.
 	GetOrBuildProducer(ProducerBuilder) (p Producer, close func())
 	// Shutdown shuts down the SubConn gracefully.  Any started RPCs will be
 	// allowed to complete.  No future calls should be made on the SubConn.
@@ -452,8 +455,10 @@ type ProducerBuilder interface {
 	// Build creates a Producer.  The first parameter is always a
 	// grpc.ClientConnInterface (a type to allow creating RPCs/streams on the
 	// associated SubConn), but is declared as `any` to avoid a dependency
-	// cycle.  Should also return a close function that will be called when all
-	// references to the Producer have been given up.
+	// cycle.  Build also returns a close function that will be called when all
+	// references to the Producer have been given up for a SubConn, or when a
+	// connectivity state change occurs on the SubConn.  The close function
+	// should always block until all asynchronous cleanup work is completed.
 	Build(grpcClientConnInterface any) (p Producer, close func())
 }
 
diff --git a/vendor/google.golang.org/grpc/balancer/base/balancer.go b/vendor/google.golang.org/grpc/balancer/base/balancer.go
index 2b87bd79c7..d5ed172ae6 100644
--- a/vendor/google.golang.org/grpc/balancer/base/balancer.go
+++ b/vendor/google.golang.org/grpc/balancer/base/balancer.go
@@ -133,7 +133,7 @@ func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) error {
 		}
 	}
 	// If resolver state contains no addresses, return an error so ClientConn
-	// will trigger re-resolve. Also records this as an resolver error, so when
+	// will trigger re-resolve. Also records this as a resolver error, so when
 	// the overall state turns transient failure, the error message will have
 	// the zero address information.
 	if len(s.ResolverState.Addresses) == 0 {
diff --git a/vendor/google.golang.org/grpc/balancer/pickfirst/internal/internal.go b/vendor/google.golang.org/grpc/balancer/pickfirst/internal/internal.go
new file mode 100644
index 0000000000..c519789458
--- /dev/null
+++ b/vendor/google.golang.org/grpc/balancer/pickfirst/internal/internal.go
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2024 gRPC authors.
+ *
+ * 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 internal contains code internal to the pickfirst package.
+package internal
+
+import "math/rand"
+
+// RandShuffle pseudo-randomizes the order of addresses.
+var RandShuffle = rand.Shuffle
diff --git a/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go b/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go
index 4d69b4052f..e069346a75 100644
--- a/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go
+++ b/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirst.go
@@ -26,18 +26,23 @@ import (
 	"math/rand"
 
 	"google.golang.org/grpc/balancer"
+	"google.golang.org/grpc/balancer/pickfirst/internal"
 	"google.golang.org/grpc/connectivity"
 	"google.golang.org/grpc/grpclog"
-	"google.golang.org/grpc/internal"
+	"google.golang.org/grpc/internal/envconfig"
 	internalgrpclog "google.golang.org/grpc/internal/grpclog"
 	"google.golang.org/grpc/internal/pretty"
 	"google.golang.org/grpc/resolver"
 	"google.golang.org/grpc/serviceconfig"
+
+	_ "google.golang.org/grpc/balancer/pickfirst/pickfirstleaf" // For automatically registering the new pickfirst if required.
 )
 
 func init() {
+	if envconfig.NewPickFirstEnabled {
+		return
+	}
 	balancer.Register(pickfirstBuilder{})
-	internal.ShuffleAddressListForTesting = func(n int, swap func(i, j int)) { rand.Shuffle(n, swap) }
 }
 
 var logger = grpclog.Component("pick-first-lb")
@@ -103,10 +108,13 @@ func (b *pickfirstBalancer) ResolverError(err error) {
 	})
 }
 
+// Shuffler is an interface for shuffling an address list.
 type Shuffler interface {
 	ShuffleAddressListForTesting(n int, swap func(i, j int))
 }
 
+// ShuffleAddressListForTesting pseudo-randomizes the order of addresses.  n
+// is the number of elements.  swap swaps the elements with indexes i and j.
 func ShuffleAddressListForTesting(n int, swap func(i, j int)) { rand.Shuffle(n, swap) }
 
 func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState) error {
@@ -140,7 +148,7 @@ func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState
 		// within each endpoint. - A61
 		if cfg.ShuffleAddressList {
 			endpoints = append([]resolver.Endpoint{}, endpoints...)
-			internal.ShuffleAddressListForTesting.(func(int, func(int, int)))(len(endpoints), func(i, j int) { endpoints[i], endpoints[j] = endpoints[j], endpoints[i] })
+			internal.RandShuffle(len(endpoints), func(i, j int) { endpoints[i], endpoints[j] = endpoints[j], endpoints[i] })
 		}
 
 		// "Flatten the list by concatenating the ordered list of addresses for each
diff --git a/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirstleaf/pickfirstleaf.go b/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirstleaf/pickfirstleaf.go
new file mode 100644
index 0000000000..985b6edc7f
--- /dev/null
+++ b/vendor/google.golang.org/grpc/balancer/pickfirst/pickfirstleaf/pickfirstleaf.go
@@ -0,0 +1,625 @@
+/*
+ *
+ * Copyright 2024 gRPC authors.
+ *
+ * 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 pickfirstleaf contains the pick_first load balancing policy which
+// will be the universal leaf policy after dualstack changes are implemented.
+//
+// # Experimental
+//
+// Notice: This package is EXPERIMENTAL and may be changed or removed in a
+// later release.
+package pickfirstleaf
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"sync"
+
+	"google.golang.org/grpc/balancer"
+	"google.golang.org/grpc/balancer/pickfirst/internal"
+	"google.golang.org/grpc/connectivity"
+	"google.golang.org/grpc/grpclog"
+	"google.golang.org/grpc/internal/envconfig"
+	internalgrpclog "google.golang.org/grpc/internal/grpclog"
+	"google.golang.org/grpc/internal/pretty"
+	"google.golang.org/grpc/resolver"
+	"google.golang.org/grpc/serviceconfig"
+)
+
+func init() {
+	if envconfig.NewPickFirstEnabled {
+		// Register as the default pick_first balancer.
+		Name = "pick_first"
+	}
+	balancer.Register(pickfirstBuilder{})
+}
+
+var (
+	logger = grpclog.Component("pick-first-leaf-lb")
+	// Name is the name of the pick_first_leaf balancer.
+	// It is changed to "pick_first" in init() if this balancer is to be
+	// registered as the default pickfirst.
+	Name = "pick_first_leaf"
+)
+
+// TODO: change to pick-first when this becomes the default pick_first policy.
+const logPrefix = "[pick-first-leaf-lb %p] "
+
+type pickfirstBuilder struct{}
+
+func (pickfirstBuilder) Build(cc balancer.ClientConn, _ balancer.BuildOptions) balancer.Balancer {
+	b := &pickfirstBalancer{
+		cc:          cc,
+		addressList: addressList{},
+		subConns:    resolver.NewAddressMap(),
+		state:       connectivity.Connecting,
+		mu:          sync.Mutex{},
+	}
+	b.logger = internalgrpclog.NewPrefixLogger(logger, fmt.Sprintf(logPrefix, b))
+	return b
+}
+
+func (b pickfirstBuilder) Name() string {
+	return Name
+}
+
+func (pickfirstBuilder) ParseConfig(js json.RawMessage) (serviceconfig.LoadBalancingConfig, error) {
+	var cfg pfConfig
+	if err := json.Unmarshal(js, &cfg); err != nil {
+		return nil, fmt.Errorf("pickfirst: unable to unmarshal LB policy config: %s, error: %v", string(js), err)
+	}
+	return cfg, nil
+}
+
+type pfConfig struct {
+	serviceconfig.LoadBalancingConfig `json:"-"`
+
+	// If set to true, instructs the LB policy to shuffle the order of the list
+	// of endpoints received from the name resolver before attempting to
+	// connect to them.
+	ShuffleAddressList bool `json:"shuffleAddressList"`
+}
+
+// scData keeps track of the current state of the subConn.
+// It is not safe for concurrent access.
+type scData struct {
+	// The following fields are initialized at build time and read-only after
+	// that.
+	subConn balancer.SubConn
+	addr    resolver.Address
+
+	state   connectivity.State
+	lastErr error
+}
+
+func (b *pickfirstBalancer) newSCData(addr resolver.Address) (*scData, error) {
+	sd := &scData{
+		state: connectivity.Idle,
+		addr:  addr,
+	}
+	sc, err := b.cc.NewSubConn([]resolver.Address{addr}, balancer.NewSubConnOptions{
+		StateListener: func(state balancer.SubConnState) {
+			b.updateSubConnState(sd, state)
+		},
+	})
+	if err != nil {
+		return nil, err
+	}
+	sd.subConn = sc
+	return sd, nil
+}
+
+type pickfirstBalancer struct {
+	// The following fields are initialized at build time and read-only after
+	// that and therefore do not need to be guarded by a mutex.
+	logger *internalgrpclog.PrefixLogger
+	cc     balancer.ClientConn
+
+	// The mutex is used to ensure synchronization of updates triggered
+	// from the idle picker and the already serialized resolver,
+	// SubConn state updates.
+	mu    sync.Mutex
+	state connectivity.State
+	// scData for active subonns mapped by address.
+	subConns    *resolver.AddressMap
+	addressList addressList
+	firstPass   bool
+	numTF       int
+}
+
+// ResolverError is called by the ClientConn when the name resolver produces
+// an error or when pickfirst determined the resolver update to be invalid.
+func (b *pickfirstBalancer) ResolverError(err error) {
+	b.mu.Lock()
+	defer b.mu.Unlock()
+	b.resolverErrorLocked(err)
+}
+
+func (b *pickfirstBalancer) resolverErrorLocked(err error) {
+	if b.logger.V(2) {
+		b.logger.Infof("Received error from the name resolver: %v", err)
+	}
+
+	// The picker will not change since the balancer does not currently
+	// report an error. If the balancer hasn't received a single good resolver
+	// update yet, transition to TRANSIENT_FAILURE.
+	if b.state != connectivity.TransientFailure && b.addressList.size() > 0 {
+		if b.logger.V(2) {
+			b.logger.Infof("Ignoring resolver error because balancer is using a previous good update.")
+		}
+		return
+	}
+
+	b.cc.UpdateState(balancer.State{
+		ConnectivityState: connectivity.TransientFailure,
+		Picker:            &picker{err: fmt.Errorf("name resolver error: %v", err)},
+	})
+}
+
+func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState) error {
+	b.mu.Lock()
+	defer b.mu.Unlock()
+	if len(state.ResolverState.Addresses) == 0 && len(state.ResolverState.Endpoints) == 0 {
+		// Cleanup state pertaining to the previous resolver state.
+		// Treat an empty address list like an error by calling b.ResolverError.
+		b.state = connectivity.TransientFailure
+		b.closeSubConnsLocked()
+		b.addressList.updateAddrs(nil)
+		b.resolverErrorLocked(errors.New("produced zero addresses"))
+		return balancer.ErrBadResolverState
+	}
+	cfg, ok := state.BalancerConfig.(pfConfig)
+	if state.BalancerConfig != nil && !ok {
+		return fmt.Errorf("pickfirst: received illegal BalancerConfig (type %T): %v: %w", state.BalancerConfig, state.BalancerConfig, balancer.ErrBadResolverState)
+	}
+
+	if b.logger.V(2) {
+		b.logger.Infof("Received new config %s, resolver state %s", pretty.ToJSON(cfg), pretty.ToJSON(state.ResolverState))
+	}
+
+	var newAddrs []resolver.Address
+	if endpoints := state.ResolverState.Endpoints; len(endpoints) != 0 {
+		// Perform the optional shuffling described in gRFC A62. The shuffling
+		// will change the order of endpoints but not touch the order of the
+		// addresses within each endpoint. - A61
+		if cfg.ShuffleAddressList {
+			endpoints = append([]resolver.Endpoint{}, endpoints...)
+			internal.RandShuffle(len(endpoints), func(i, j int) { endpoints[i], endpoints[j] = endpoints[j], endpoints[i] })
+		}
+
+		// "Flatten the list by concatenating the ordered list of addresses for
+		// each of the endpoints, in order." - A61
+		for _, endpoint := range endpoints {
+			// "In the flattened list, interleave addresses from the two address
+			// families, as per RFC-8305 section 4." - A61
+			// TODO: support the above language.
+			newAddrs = append(newAddrs, endpoint.Addresses...)
+		}
+	} else {
+		// Endpoints not set, process addresses until we migrate resolver
+		// emissions fully to Endpoints. The top channel does wrap emitted
+		// addresses with endpoints, however some balancers such as weighted
+		// target do not forward the corresponding correct endpoints down/split
+		// endpoints properly. Once all balancers correctly forward endpoints
+		// down, can delete this else conditional.
+		newAddrs = state.ResolverState.Addresses
+		if cfg.ShuffleAddressList {
+			newAddrs = append([]resolver.Address{}, newAddrs...)
+			internal.RandShuffle(len(endpoints), func(i, j int) { endpoints[i], endpoints[j] = endpoints[j], endpoints[i] })
+		}
+	}
+
+	// If an address appears in multiple endpoints or in the same endpoint
+	// multiple times, we keep it only once. We will create only one SubConn
+	// for the address because an AddressMap is used to store SubConns.
+	// Not de-duplicating would result in attempting to connect to the same
+	// SubConn multiple times in the same pass. We don't want this.
+	newAddrs = deDupAddresses(newAddrs)
+
+	// Since we have a new set of addresses, we are again at first pass.
+	b.firstPass = true
+
+	// If the previous ready SubConn exists in new address list,
+	// keep this connection and don't create new SubConns.
+	prevAddr := b.addressList.currentAddress()
+	prevAddrsCount := b.addressList.size()
+	b.addressList.updateAddrs(newAddrs)
+	if b.state == connectivity.Ready && b.addressList.seekTo(prevAddr) {
+		return nil
+	}
+
+	b.reconcileSubConnsLocked(newAddrs)
+	// If it's the first resolver update or the balancer was already READY
+	// (but the new address list does not contain the ready SubConn) or
+	// CONNECTING, enter CONNECTING.
+	// We may be in TRANSIENT_FAILURE due to a previous empty address list,
+	// we should still enter CONNECTING because the sticky TF behaviour
+	//  mentioned in A62 applies only when the TRANSIENT_FAILURE is reported
+	// due to connectivity failures.
+	if b.state == connectivity.Ready || b.state == connectivity.Connecting || prevAddrsCount == 0 {
+		// Start connection attempt at first address.
+		b.state = connectivity.Connecting
+		b.cc.UpdateState(balancer.State{
+			ConnectivityState: connectivity.Connecting,
+			Picker:            &picker{err: balancer.ErrNoSubConnAvailable},
+		})
+		b.requestConnectionLocked()
+	} else if b.state == connectivity.TransientFailure {
+		// If we're in TRANSIENT_FAILURE, we stay in TRANSIENT_FAILURE until
+		// we're READY. See A62.
+		b.requestConnectionLocked()
+	}
+	return nil
+}
+
+// UpdateSubConnState is unused as a StateListener is always registered when
+// creating SubConns.
+func (b *pickfirstBalancer) UpdateSubConnState(subConn balancer.SubConn, state balancer.SubConnState) {
+	b.logger.Errorf("UpdateSubConnState(%v, %+v) called unexpectedly", subConn, state)
+}
+
+func (b *pickfirstBalancer) Close() {
+	b.mu.Lock()
+	defer b.mu.Unlock()
+	b.closeSubConnsLocked()
+	b.state = connectivity.Shutdown
+}
+
+// ExitIdle moves the balancer out of idle state. It can be called concurrently
+// by the idlePicker and clientConn so access to variables should be
+// synchronized.
+func (b *pickfirstBalancer) ExitIdle() {
+	b.mu.Lock()
+	defer b.mu.Unlock()
+	if b.state == connectivity.Idle && b.addressList.currentAddress() == b.addressList.first() {
+		b.firstPass = true
+		b.requestConnectionLocked()
+	}
+}
+
+func (b *pickfirstBalancer) closeSubConnsLocked() {
+	for _, sd := range b.subConns.Values() {
+		sd.(*scData).subConn.Shutdown()
+	}
+	b.subConns = resolver.NewAddressMap()
+}
+
+// deDupAddresses ensures that each address appears only once in the slice.
+func deDupAddresses(addrs []resolver.Address) []resolver.Address {
+	seenAddrs := resolver.NewAddressMap()
+	retAddrs := []resolver.Address{}
+
+	for _, addr := range addrs {
+		if _, ok := seenAddrs.Get(addr); ok {
+			continue
+		}
+		retAddrs = append(retAddrs, addr)
+	}
+	return retAddrs
+}
+
+// reconcileSubConnsLocked updates the active subchannels based on a new address
+// list from the resolver. It does this by:
+//   - closing subchannels: any existing subchannels associated with addresses
+//     that are no longer in the updated list are shut down.
+//   - removing subchannels: entries for these closed subchannels are removed
+//     from the subchannel map.
+//
+// This ensures that the subchannel map accurately reflects the current set of
+// addresses received from the name resolver.
+func (b *pickfirstBalancer) reconcileSubConnsLocked(newAddrs []resolver.Address) {
+	newAddrsMap := resolver.NewAddressMap()
+	for _, addr := range newAddrs {
+		newAddrsMap.Set(addr, true)
+	}
+
+	for _, oldAddr := range b.subConns.Keys() {
+		if _, ok := newAddrsMap.Get(oldAddr); ok {
+			continue
+		}
+		val, _ := b.subConns.Get(oldAddr)
+		val.(*scData).subConn.Shutdown()
+		b.subConns.Delete(oldAddr)
+	}
+}
+
+// shutdownRemainingLocked shuts down remaining subConns. Called when a subConn
+// becomes ready, which means that all other subConn must be shutdown.
+func (b *pickfirstBalancer) shutdownRemainingLocked(selected *scData) {
+	for _, v := range b.subConns.Values() {
+		sd := v.(*scData)
+		if sd.subConn != selected.subConn {
+			sd.subConn.Shutdown()
+		}
+	}
+	b.subConns = resolver.NewAddressMap()
+	b.subConns.Set(selected.addr, selected)
+}
+
+// requestConnectionLocked starts connecting on the subchannel corresponding to
+// the current address. If no subchannel exists, one is created. If the current
+// subchannel is in TransientFailure, a connection to the next address is
+// attempted until a subchannel is found.
+func (b *pickfirstBalancer) requestConnectionLocked() {
+	if !b.addressList.isValid() {
+		return
+	}
+	var lastErr error
+	for valid := true; valid; valid = b.addressList.increment() {
+		curAddr := b.addressList.currentAddress()
+		sd, ok := b.subConns.Get(curAddr)
+		if !ok {
+			var err error
+			// We want to assign the new scData to sd from the outer scope,
+			// hence we can't use := below.
+			sd, err = b.newSCData(curAddr)
+			if err != nil {
+				// This should never happen, unless the clientConn is being shut
+				// down.
+				if b.logger.V(2) {
+					b.logger.Infof("Failed to create a subConn for address %v: %v", curAddr.String(), err)
+				}
+				// Do nothing, the LB policy will be closed soon.
+				return
+			}
+			b.subConns.Set(curAddr, sd)
+		}
+
+		scd := sd.(*scData)
+		switch scd.state {
+		case connectivity.Idle:
+			scd.subConn.Connect()
+		case connectivity.TransientFailure:
+			// Try the next address.
+			lastErr = scd.lastErr
+			continue
+		case connectivity.Ready:
+			// Should never happen.
+			b.logger.Errorf("Requesting a connection even though we have a READY SubConn")
+		case connectivity.Shutdown:
+			// Should never happen.
+			b.logger.Errorf("SubConn with state SHUTDOWN present in SubConns map")
+		case connectivity.Connecting:
+			// Wait for the SubConn to report success or failure.
+		}
+		return
+	}
+	// All the remaining addresses in the list are in TRANSIENT_FAILURE, end the
+	// first pass.
+	b.endFirstPassLocked(lastErr)
+}
+
+func (b *pickfirstBalancer) updateSubConnState(sd *scData, newState balancer.SubConnState) {
+	b.mu.Lock()
+	defer b.mu.Unlock()
+	oldState := sd.state
+	sd.state = newState.ConnectivityState
+	// Previously relevant SubConns can still callback with state updates.
+	// To prevent pickers from returning these obsolete SubConns, this logic
+	// is included to check if the current list of active SubConns includes this
+	// SubConn.
+	if activeSD, found := b.subConns.Get(sd.addr); !found || activeSD != sd {
+		return
+	}
+	if newState.ConnectivityState == connectivity.Shutdown {
+		return
+	}
+
+	if newState.ConnectivityState == connectivity.Ready {
+		b.shutdownRemainingLocked(sd)
+		if !b.addressList.seekTo(sd.addr) {
+			// This should not fail as we should have only one SubConn after
+			// entering READY. The SubConn should be present in the addressList.
+			b.logger.Errorf("Address %q not found address list in  %v", sd.addr, b.addressList.addresses)
+			return
+		}
+		b.state = connectivity.Ready
+		b.cc.UpdateState(balancer.State{
+			ConnectivityState: connectivity.Ready,
+			Picker:            &picker{result: balancer.PickResult{SubConn: sd.subConn}},
+		})
+		return
+	}
+
+	// If the LB policy is READY, and it receives a subchannel state change,
+	// it means that the READY subchannel has failed.
+	// A SubConn can also transition from CONNECTING directly to IDLE when
+	// a transport is successfully created, but the connection fails
+	// before the SubConn can send the notification for READY. We treat
+	// this as a successful connection and transition to IDLE.
+	if (b.state == connectivity.Ready && newState.ConnectivityState != connectivity.Ready) || (oldState == connectivity.Connecting && newState.ConnectivityState == connectivity.Idle) {
+		// Once a transport fails, the balancer enters IDLE and starts from
+		// the first address when the picker is used.
+		b.shutdownRemainingLocked(sd)
+		b.state = connectivity.Idle
+		b.addressList.reset()
+		b.cc.UpdateState(balancer.State{
+			ConnectivityState: connectivity.Idle,
+			Picker:            &idlePicker{exitIdle: sync.OnceFunc(b.ExitIdle)},
+		})
+		return
+	}
+
+	if b.firstPass {
+		switch newState.ConnectivityState {
+		case connectivity.Connecting:
+			// The balancer can be in either IDLE, CONNECTING or
+			// TRANSIENT_FAILURE. If it's in TRANSIENT_FAILURE, stay in
+			// TRANSIENT_FAILURE until it's READY. See A62.
+			// If the balancer is already in CONNECTING, no update is needed.
+			if b.state == connectivity.Idle {
+				b.state = connectivity.Connecting
+				b.cc.UpdateState(balancer.State{
+					ConnectivityState: connectivity.Connecting,
+					Picker:            &picker{err: balancer.ErrNoSubConnAvailable},
+				})
+			}
+		case connectivity.TransientFailure:
+			sd.lastErr = newState.ConnectionError
+			// Since we're re-using common SubConns while handling resolver
+			// updates, we could receive an out of turn TRANSIENT_FAILURE from
+			// a pass over the previous address list. We ignore such updates.
+
+			if curAddr := b.addressList.currentAddress(); !equalAddressIgnoringBalAttributes(&curAddr, &sd.addr) {
+				return
+			}
+			if b.addressList.increment() {
+				b.requestConnectionLocked()
+				return
+			}
+			// End of the first pass.
+			b.endFirstPassLocked(newState.ConnectionError)
+		}
+		return
+	}
+
+	// We have finished the first pass, keep re-connecting failing SubConns.
+	switch newState.ConnectivityState {
+	case connectivity.TransientFailure:
+		b.numTF = (b.numTF + 1) % b.subConns.Len()
+		sd.lastErr = newState.ConnectionError
+		if b.numTF%b.subConns.Len() == 0 {
+			b.cc.UpdateState(balancer.State{
+				ConnectivityState: connectivity.TransientFailure,
+				Picker:            &picker{err: newState.ConnectionError},
+			})
+		}
+		// We don't need to request re-resolution since the SubConn already
+		// does that before reporting TRANSIENT_FAILURE.
+		// TODO: #7534 - Move re-resolution requests from SubConn into
+		// pick_first.
+	case connectivity.Idle:
+		sd.subConn.Connect()
+	}
+}
+
+func (b *pickfirstBalancer) endFirstPassLocked(lastErr error) {
+	b.firstPass = false
+	b.numTF = 0
+	b.state = connectivity.TransientFailure
+
+	b.cc.UpdateState(balancer.State{
+		ConnectivityState: connectivity.TransientFailure,
+		Picker:            &picker{err: lastErr},
+	})
+	// Start re-connecting all the SubConns that are already in IDLE.
+	for _, v := range b.subConns.Values() {
+		sd := v.(*scData)
+		if sd.state == connectivity.Idle {
+			sd.subConn.Connect()
+		}
+	}
+}
+
+type picker struct {
+	result balancer.PickResult
+	err    error
+}
+
+func (p *picker) Pick(balancer.PickInfo) (balancer.PickResult, error) {
+	return p.result, p.err
+}
+
+// idlePicker is used when the SubConn is IDLE and kicks the SubConn into
+// CONNECTING when Pick is called.
+type idlePicker struct {
+	exitIdle func()
+}
+
+func (i *idlePicker) Pick(balancer.PickInfo) (balancer.PickResult, error) {
+	i.exitIdle()
+	return balancer.PickResult{}, balancer.ErrNoSubConnAvailable
+}
+
+// addressList manages sequentially iterating over addresses present in a list
+// of endpoints. It provides a 1 dimensional view of the addresses present in
+// the endpoints.
+// This type is not safe for concurrent access.
+type addressList struct {
+	addresses []resolver.Address
+	idx       int
+}
+
+func (al *addressList) isValid() bool {
+	return al.idx < len(al.addresses)
+}
+
+func (al *addressList) size() int {
+	return len(al.addresses)
+}
+
+// increment moves to the next index in the address list.
+// This method returns false if it went off the list, true otherwise.
+func (al *addressList) increment() bool {
+	if !al.isValid() {
+		return false
+	}
+	al.idx++
+	return al.idx < len(al.addresses)
+}
+
+// currentAddress returns the current address pointed to in the addressList.
+// If the list is in an invalid state, it returns an empty address instead.
+func (al *addressList) currentAddress() resolver.Address {
+	if !al.isValid() {
+		return resolver.Address{}
+	}
+	return al.addresses[al.idx]
+}
+
+// first returns the first address in the list. If the list is empty, it returns
+// an empty address instead.
+func (al *addressList) first() resolver.Address {
+	if len(al.addresses) == 0 {
+		return resolver.Address{}
+	}
+	return al.addresses[0]
+}
+
+func (al *addressList) reset() {
+	al.idx = 0
+}
+
+func (al *addressList) updateAddrs(addrs []resolver.Address) {
+	al.addresses = addrs
+	al.reset()
+}
+
+// seekTo returns false if the needle was not found and the current index was
+// left unchanged.
+func (al *addressList) seekTo(needle resolver.Address) bool {
+	for ai, addr := range al.addresses {
+		if !equalAddressIgnoringBalAttributes(&addr, &needle) {
+			continue
+		}
+		al.idx = ai
+		return true
+	}
+	return false
+}
+
+// equalAddressIgnoringBalAttributes returns true is a and b are considered
+// equal. This is different from the Equal method on the resolver.Address type
+// which considers all fields to determine equality. Here, we only consider
+// fields that are meaningful to the SubConn.
+func equalAddressIgnoringBalAttributes(a, b *resolver.Address) bool {
+	return a.Addr == b.Addr && a.ServerName == b.ServerName &&
+		a.Attributes.Equal(b.Attributes) &&
+		a.Metadata == b.Metadata
+}
diff --git a/vendor/google.golang.org/grpc/balancer_wrapper.go b/vendor/google.golang.org/grpc/balancer_wrapper.go
index 8ad6ce2f09..2a4f2878ae 100644
--- a/vendor/google.golang.org/grpc/balancer_wrapper.go
+++ b/vendor/google.golang.org/grpc/balancer_wrapper.go
@@ -24,12 +24,14 @@ import (
 	"sync"
 
 	"google.golang.org/grpc/balancer"
+	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/connectivity"
 	"google.golang.org/grpc/internal"
 	"google.golang.org/grpc/internal/balancer/gracefulswitch"
 	"google.golang.org/grpc/internal/channelz"
 	"google.golang.org/grpc/internal/grpcsync"
 	"google.golang.org/grpc/resolver"
+	"google.golang.org/grpc/status"
 )
 
 var setConnectedAddress = internal.SetConnectedAddress.(func(*balancer.SubConnState, resolver.Address))
@@ -256,8 +258,8 @@ type acBalancerWrapper struct {
 	ccb           *ccBalancerWrapper // read-only
 	stateListener func(balancer.SubConnState)
 
-	mu        sync.Mutex
-	producers map[balancer.ProducerBuilder]*refCountedProducer
+	producersMu sync.Mutex
+	producers   map[balancer.ProducerBuilder]*refCountedProducer
 }
 
 // updateState is invoked by grpc to push a subConn state update to the
@@ -267,6 +269,9 @@ func (acbw *acBalancerWrapper) updateState(s connectivity.State, curAddr resolve
 		if ctx.Err() != nil || acbw.ccb.balancer == nil {
 			return
 		}
+		// Invalidate all producers on any state change.
+		acbw.closeProducers()
+
 		// Even though it is optional for balancers, gracefulswitch ensures
 		// opts.StateListener is set, so this cannot ever be nil.
 		// TODO: delete this comment when UpdateSubConnState is removed.
@@ -275,16 +280,6 @@ func (acbw *acBalancerWrapper) updateState(s connectivity.State, curAddr resolve
 			setConnectedAddress(&scs, curAddr)
 		}
 		acbw.stateListener(scs)
-		acbw.ac.mu.Lock()
-		defer acbw.ac.mu.Unlock()
-		if s == connectivity.Ready {
-			// When changing states to READY, reset stateReadyChan.  Wait until
-			// after we notify the LB policy's listener(s) in order to prevent
-			// ac.getTransport() from unblocking before the LB policy starts
-			// tracking the subchannel as READY.
-			close(acbw.ac.stateReadyChan)
-			acbw.ac.stateReadyChan = make(chan struct{})
-		}
 	})
 }
 
@@ -301,6 +296,7 @@ func (acbw *acBalancerWrapper) Connect() {
 }
 
 func (acbw *acBalancerWrapper) Shutdown() {
+	acbw.closeProducers()
 	acbw.ccb.cc.removeAddrConn(acbw.ac, errConnDrain)
 }
 
@@ -308,9 +304,10 @@ func (acbw *acBalancerWrapper) Shutdown() {
 // ready, blocks until it is or ctx expires.  Returns an error when the context
 // expires or the addrConn is shut down.
 func (acbw *acBalancerWrapper) NewStream(ctx context.Context, desc *StreamDesc, method string, opts ...CallOption) (ClientStream, error) {
-	transport, err := acbw.ac.getTransport(ctx)
-	if err != nil {
-		return nil, err
+	transport := acbw.ac.getReadyTransport()
+	if transport == nil {
+		return nil, status.Errorf(codes.Unavailable, "SubConn state is not Ready")
+
 	}
 	return newNonRetryClientStream(ctx, desc, method, transport, acbw.ac, opts...)
 }
@@ -335,8 +332,8 @@ type refCountedProducer struct {
 }
 
 func (acbw *acBalancerWrapper) GetOrBuildProducer(pb balancer.ProducerBuilder) (balancer.Producer, func()) {
-	acbw.mu.Lock()
-	defer acbw.mu.Unlock()
+	acbw.producersMu.Lock()
+	defer acbw.producersMu.Unlock()
 
 	// Look up existing producer from this builder.
 	pData := acbw.producers[pb]
@@ -353,13 +350,26 @@ func (acbw *acBalancerWrapper) GetOrBuildProducer(pb balancer.ProducerBuilder) (
 	// and delete the refCountedProducer from the map if the total reference
 	// count goes to zero.
 	unref := func() {
-		acbw.mu.Lock()
+		acbw.producersMu.Lock()
+		// If closeProducers has already closed this producer instance, refs is
+		// set to 0, so the check after decrementing will never pass, and the
+		// producer will not be double-closed.
 		pData.refs--
 		if pData.refs == 0 {
 			defer pData.close() // Run outside the acbw mutex
 			delete(acbw.producers, pb)
 		}
-		acbw.mu.Unlock()
+		acbw.producersMu.Unlock()
 	}
 	return pData.producer, grpcsync.OnceFunc(unref)
 }
+
+func (acbw *acBalancerWrapper) closeProducers() {
+	acbw.producersMu.Lock()
+	defer acbw.producersMu.Unlock()
+	for pb, pData := range acbw.producers {
+		pData.refs = 0
+		pData.close()
+		delete(acbw.producers, pb)
+	}
+}
diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go
index 9c8850e3fd..19763f8edd 100644
--- a/vendor/google.golang.org/grpc/clientconn.go
+++ b/vendor/google.golang.org/grpc/clientconn.go
@@ -825,14 +825,13 @@ func (cc *ClientConn) newAddrConnLocked(addrs []resolver.Address, opts balancer.
 	}
 
 	ac := &addrConn{
-		state:          connectivity.Idle,
-		cc:             cc,
-		addrs:          copyAddresses(addrs),
-		scopts:         opts,
-		dopts:          cc.dopts,
-		channelz:       channelz.RegisterSubChannel(cc.channelz, ""),
-		resetBackoff:   make(chan struct{}),
-		stateReadyChan: make(chan struct{}),
+		state:        connectivity.Idle,
+		cc:           cc,
+		addrs:        copyAddresses(addrs),
+		scopts:       opts,
+		dopts:        cc.dopts,
+		channelz:     channelz.RegisterSubChannel(cc.channelz, ""),
+		resetBackoff: make(chan struct{}),
 	}
 	ac.ctx, ac.cancel = context.WithCancel(cc.ctx)
 	// Start with our address set to the first address; this may be updated if
@@ -1141,10 +1140,15 @@ func (cc *ClientConn) Close() error {
 
 	<-cc.resolverWrapper.serializer.Done()
 	<-cc.balancerWrapper.serializer.Done()
-
+	var wg sync.WaitGroup
 	for ac := range conns {
-		ac.tearDown(ErrClientConnClosing)
+		wg.Add(1)
+		go func(ac *addrConn) {
+			defer wg.Done()
+			ac.tearDown(ErrClientConnClosing)
+		}(ac)
 	}
+	wg.Wait()
 	cc.addTraceEvent("deleted")
 	// TraceEvent needs to be called before RemoveEntry, as TraceEvent may add
 	// trace reference to the entity being deleted, and thus prevent it from being
@@ -1179,8 +1183,7 @@ type addrConn struct {
 	addrs   []resolver.Address // All addresses that the resolver resolved to.
 
 	// Use updateConnectivityState for updating addrConn's connectivity state.
-	state          connectivity.State
-	stateReadyChan chan struct{} // closed and recreated on every READY state change.
+	state connectivity.State
 
 	backoffIdx   int // Needs to be stateful for resetConnectBackoff.
 	resetBackoff chan struct{}
@@ -1251,6 +1254,8 @@ func (ac *addrConn) resetTransportAndUnlock() {
 	ac.mu.Unlock()
 
 	if err := ac.tryAllAddrs(acCtx, addrs, connectDeadline); err != nil {
+		// TODO: #7534 - Move re-resolution requests into the pick_first LB policy
+		// to ensure one resolution request per pass instead of per subconn failure.
 		ac.cc.resolveNow(resolver.ResolveNowOptions{})
 		ac.mu.Lock()
 		if acCtx.Err() != nil {
@@ -1292,7 +1297,7 @@ func (ac *addrConn) resetTransportAndUnlock() {
 	ac.mu.Unlock()
 }
 
-// tryAllAddrs tries to creates a connection to the addresses, and stop when at
+// tryAllAddrs tries to create a connection to the addresses, and stop when at
 // the first successful one. It returns an error if no address was successfully
 // connected, or updates ac appropriately with the new transport.
 func (ac *addrConn) tryAllAddrs(ctx context.Context, addrs []resolver.Address, connectDeadline time.Time) error {
@@ -1504,29 +1509,6 @@ func (ac *addrConn) getReadyTransport() transport.ClientTransport {
 	return nil
 }
 
-// getTransport waits until the addrconn is ready and returns the transport.
-// If the context expires first, returns an appropriate status.  If the
-// addrConn is stopped first, returns an Unavailable status error.
-func (ac *addrConn) getTransport(ctx context.Context) (transport.ClientTransport, error) {
-	for ctx.Err() == nil {
-		ac.mu.Lock()
-		t, state, sc := ac.transport, ac.state, ac.stateReadyChan
-		ac.mu.Unlock()
-		if state == connectivity.Ready {
-			return t, nil
-		}
-		if state == connectivity.Shutdown {
-			return nil, status.Errorf(codes.Unavailable, "SubConn shutting down")
-		}
-
-		select {
-		case <-ctx.Done():
-		case <-sc:
-		}
-	}
-	return nil, status.FromContextError(ctx.Err()).Err()
-}
-
 // tearDown starts to tear down the addrConn.
 //
 // Note that tearDown doesn't remove ac from ac.cc.conns, so the addrConn struct
diff --git a/vendor/google.golang.org/grpc/credentials/tls.go b/vendor/google.golang.org/grpc/credentials/tls.go
index 4114358545..e163a473df 100644
--- a/vendor/google.golang.org/grpc/credentials/tls.go
+++ b/vendor/google.golang.org/grpc/credentials/tls.go
@@ -200,25 +200,40 @@ var tls12ForbiddenCipherSuites = map[uint16]struct{}{
 
 // NewTLS uses c to construct a TransportCredentials based on TLS.
 func NewTLS(c *tls.Config) TransportCredentials {
-	tc := &tlsCreds{credinternal.CloneTLSConfig(c)}
-	tc.config.NextProtos = credinternal.AppendH2ToNextProtos(tc.config.NextProtos)
+	config := applyDefaults(c)
+	if config.GetConfigForClient != nil {
+		oldFn := config.GetConfigForClient
+		config.GetConfigForClient = func(hello *tls.ClientHelloInfo) (*tls.Config, error) {
+			cfgForClient, err := oldFn(hello)
+			if err != nil || cfgForClient == nil {
+				return cfgForClient, err
+			}
+			return applyDefaults(cfgForClient), nil
+		}
+	}
+	return &tlsCreds{config: config}
+}
+
+func applyDefaults(c *tls.Config) *tls.Config {
+	config := credinternal.CloneTLSConfig(c)
+	config.NextProtos = credinternal.AppendH2ToNextProtos(config.NextProtos)
 	// If the user did not configure a MinVersion and did not configure a
 	// MaxVersion < 1.2, use MinVersion=1.2, which is required by
 	// https://datatracker.ietf.org/doc/html/rfc7540#section-9.2
-	if tc.config.MinVersion == 0 && (tc.config.MaxVersion == 0 || tc.config.MaxVersion >= tls.VersionTLS12) {
-		tc.config.MinVersion = tls.VersionTLS12
+	if config.MinVersion == 0 && (config.MaxVersion == 0 || config.MaxVersion >= tls.VersionTLS12) {
+		config.MinVersion = tls.VersionTLS12
 	}
 	// If the user did not configure CipherSuites, use all "secure" cipher
 	// suites reported by the TLS package, but remove some explicitly forbidden
 	// by https://datatracker.ietf.org/doc/html/rfc7540#appendix-A
-	if tc.config.CipherSuites == nil {
+	if config.CipherSuites == nil {
 		for _, cs := range tls.CipherSuites() {
 			if _, ok := tls12ForbiddenCipherSuites[cs.ID]; !ok {
-				tc.config.CipherSuites = append(tc.config.CipherSuites, cs.ID)
+				config.CipherSuites = append(config.CipherSuites, cs.ID)
 			}
 		}
 	}
-	return tc
+	return config
 }
 
 // NewClientTLSFromCert constructs TLS credentials from the provided root
diff --git a/vendor/google.golang.org/grpc/dialoptions.go b/vendor/google.golang.org/grpc/dialoptions.go
index 2b285beee3..518692c3af 100644
--- a/vendor/google.golang.org/grpc/dialoptions.go
+++ b/vendor/google.golang.org/grpc/dialoptions.go
@@ -436,7 +436,7 @@ func WithTimeout(d time.Duration) DialOption {
 // option to true from the Control field. For a concrete example of how to do
 // this, see internal.NetDialerWithTCPKeepalive().
 //
-// For more information, please see [issue 23459] in the Go github repo.
+// For more information, please see [issue 23459] in the Go GitHub repo.
 //
 // [issue 23459]: https://github.com/golang/go/issues/23459
 func WithContextDialer(f func(context.Context, string) (net.Conn, error)) DialOption {
diff --git a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go
index 13821a9266..85540f86a7 100644
--- a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go
+++ b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go
@@ -33,6 +33,8 @@ type lbConfig struct {
 	childConfig  serviceconfig.LoadBalancingConfig
 }
 
+// ChildName returns the name of the child balancer of the gracefulswitch
+// Balancer.
 func ChildName(l serviceconfig.LoadBalancingConfig) string {
 	return l.(*lbConfig).childBuilder.Name()
 }
diff --git a/vendor/google.golang.org/grpc/internal/channelz/channel.go b/vendor/google.golang.org/grpc/internal/channelz/channel.go
index d7e9e1d54e..3ec662799a 100644
--- a/vendor/google.golang.org/grpc/internal/channelz/channel.go
+++ b/vendor/google.golang.org/grpc/internal/channelz/channel.go
@@ -43,6 +43,8 @@ type Channel struct {
 	// Non-zero traceRefCount means the trace of this channel cannot be deleted.
 	traceRefCount int32
 
+	// ChannelMetrics holds connectivity state, target and call metrics for the
+	// channel within channelz.
 	ChannelMetrics ChannelMetrics
 }
 
@@ -50,6 +52,8 @@ type Channel struct {
 // nesting.
 func (c *Channel) channelzIdentifier() {}
 
+// String returns a string representation of the Channel, including its parent
+// entity and ID.
 func (c *Channel) String() string {
 	if c.Parent == nil {
 		return fmt.Sprintf("Channel #%d", c.ID)
@@ -61,24 +65,31 @@ func (c *Channel) id() int64 {
 	return c.ID
 }
 
+// SubChans returns a copy of the map of sub-channels associated with the
+// Channel.
 func (c *Channel) SubChans() map[int64]string {
 	db.mu.RLock()
 	defer db.mu.RUnlock()
 	return copyMap(c.subChans)
 }
 
+// NestedChans returns a copy of the map of nested channels associated with the
+// Channel.
 func (c *Channel) NestedChans() map[int64]string {
 	db.mu.RLock()
 	defer db.mu.RUnlock()
 	return copyMap(c.nestedChans)
 }
 
+// Trace returns a copy of the Channel's trace data.
 func (c *Channel) Trace() *ChannelTrace {
 	db.mu.RLock()
 	defer db.mu.RUnlock()
 	return c.trace.copy()
 }
 
+// ChannelMetrics holds connectivity state, target and call metrics for the
+// channel within channelz.
 type ChannelMetrics struct {
 	// The current connectivity state of the channel.
 	State atomic.Pointer[connectivity.State]
@@ -136,12 +147,16 @@ func strFromPointer(s *string) string {
 	return *s
 }
 
+// String returns a string representation of the ChannelMetrics, including its
+// state, target, and call metrics.
 func (c *ChannelMetrics) String() string {
 	return fmt.Sprintf("State: %v, Target: %s, CallsStarted: %v, CallsSucceeded: %v, CallsFailed: %v, LastCallStartedTimestamp: %v",
 		c.State.Load(), strFromPointer(c.Target.Load()), c.CallsStarted.Load(), c.CallsSucceeded.Load(), c.CallsFailed.Load(), c.LastCallStartedTimestamp.Load(),
 	)
 }
 
+// NewChannelMetricForTesting creates a new instance of ChannelMetrics with
+// specified initial values for testing purposes.
 func NewChannelMetricForTesting(state connectivity.State, target string, started, succeeded, failed, timestamp int64) *ChannelMetrics {
 	c := &ChannelMetrics{}
 	c.State.Store(&state)
diff --git a/vendor/google.golang.org/grpc/internal/channelz/server.go b/vendor/google.golang.org/grpc/internal/channelz/server.go
index cdfc49d6ea..b5a8249929 100644
--- a/vendor/google.golang.org/grpc/internal/channelz/server.go
+++ b/vendor/google.golang.org/grpc/internal/channelz/server.go
@@ -59,6 +59,8 @@ func NewServerMetricsForTesting(started, succeeded, failed, timestamp int64) *Se
 	return sm
 }
 
+// CopyFrom copies the metrics data from the provided ServerMetrics
+// instance into the current instance.
 func (sm *ServerMetrics) CopyFrom(o *ServerMetrics) {
 	sm.CallsStarted.Store(o.CallsStarted.Load())
 	sm.CallsSucceeded.Store(o.CallsSucceeded.Load())
diff --git a/vendor/google.golang.org/grpc/internal/channelz/socket.go b/vendor/google.golang.org/grpc/internal/channelz/socket.go
index fa64834b25..90103847c5 100644
--- a/vendor/google.golang.org/grpc/internal/channelz/socket.go
+++ b/vendor/google.golang.org/grpc/internal/channelz/socket.go
@@ -70,13 +70,18 @@ type EphemeralSocketMetrics struct {
 	RemoteFlowControlWindow int64
 }
 
+// SocketType represents the type of socket.
 type SocketType string
 
+// SocketType can be one of these.
 const (
 	SocketTypeNormal = "NormalSocket"
 	SocketTypeListen = "ListenSocket"
 )
 
+// Socket represents a socket within channelz which includes socket
+// metrics and data related to socket activity and provides methods
+// for managing and interacting with sockets.
 type Socket struct {
 	Entity
 	SocketType       SocketType
@@ -100,6 +105,8 @@ type Socket struct {
 	Security credentials.ChannelzSecurityValue
 }
 
+// String returns a string representation of the Socket, including its parent
+// entity, socket type, and ID.
 func (ls *Socket) String() string {
 	return fmt.Sprintf("%s %s #%d", ls.Parent, ls.SocketType, ls.ID)
 }
diff --git a/vendor/google.golang.org/grpc/internal/channelz/subchannel.go b/vendor/google.golang.org/grpc/internal/channelz/subchannel.go
index 3b88e4cba8..b20802e6e9 100644
--- a/vendor/google.golang.org/grpc/internal/channelz/subchannel.go
+++ b/vendor/google.golang.org/grpc/internal/channelz/subchannel.go
@@ -47,12 +47,14 @@ func (sc *SubChannel) id() int64 {
 	return sc.ID
 }
 
+// Sockets returns a copy of the sockets map associated with the SubChannel.
 func (sc *SubChannel) Sockets() map[int64]string {
 	db.mu.RLock()
 	defer db.mu.RUnlock()
 	return copyMap(sc.sockets)
 }
 
+// Trace returns a copy of the ChannelTrace associated with the SubChannel.
 func (sc *SubChannel) Trace() *ChannelTrace {
 	db.mu.RLock()
 	defer db.mu.RUnlock()
diff --git a/vendor/google.golang.org/grpc/internal/channelz/trace.go b/vendor/google.golang.org/grpc/internal/channelz/trace.go
index 36b8674032..2bffe47776 100644
--- a/vendor/google.golang.org/grpc/internal/channelz/trace.go
+++ b/vendor/google.golang.org/grpc/internal/channelz/trace.go
@@ -79,13 +79,21 @@ type TraceEvent struct {
 	Parent   *TraceEvent
 }
 
+// ChannelTrace provides tracing information for a channel.
+// It tracks various events and metadata related to the channel's lifecycle
+// and operations.
 type ChannelTrace struct {
-	cm           *channelMap
-	clearCalled  bool
+	cm          *channelMap
+	clearCalled bool
+	// The time when the trace was created.
 	CreationTime time.Time
-	EventNum     int64
-	mu           sync.Mutex
-	Events       []*traceEvent
+	// A counter for the number of events recorded in the
+	// trace.
+	EventNum int64
+	mu       sync.Mutex
+	// A slice of traceEvent pointers representing the events recorded for
+	// this channel.
+	Events []*traceEvent
 }
 
 func (c *ChannelTrace) copy() *ChannelTrace {
@@ -175,6 +183,7 @@ var refChannelTypeToString = map[RefChannelType]string{
 	RefNormalSocket: "NormalSocket",
 }
 
+// String returns a string representation of the RefChannelType
 func (r RefChannelType) String() string {
 	return refChannelTypeToString[r]
 }
diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go
index 452985f8d8..6e7dd6b772 100644
--- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go
+++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go
@@ -50,6 +50,11 @@ var (
 	// xDS fallback is turned on. If this is unset or is false, only the first
 	// xDS server in the list of server configs will be used.
 	XDSFallbackSupport = boolFromEnv("GRPC_EXPERIMENTAL_XDS_FALLBACK", false)
+	// NewPickFirstEnabled is set if the new pickfirst leaf policy is to be used
+	// instead of the exiting pickfirst implementation. This can be enabled by
+	// setting the environment variable "GRPC_EXPERIMENTAL_ENABLE_NEW_PICK_FIRST"
+	// to "true".
+	NewPickFirstEnabled = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_NEW_PICK_FIRST", false)
 )
 
 func boolFromEnv(envVar string, def bool) bool {
diff --git a/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go b/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go
index 19b9d63927..8e8e861280 100644
--- a/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go
+++ b/vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go
@@ -53,7 +53,7 @@ func NewCallbackSerializer(ctx context.Context) *CallbackSerializer {
 	return cs
 }
 
-// TrySchedule tries to schedules the provided callback function f to be
+// TrySchedule tries to schedule the provided callback function f to be
 // executed in the order it was added. This is a best-effort operation. If the
 // context passed to NewCallbackSerializer was canceled before this method is
 // called, the callback will not be scheduled.
diff --git a/vendor/google.golang.org/grpc/internal/grpcutil/method.go b/vendor/google.golang.org/grpc/internal/grpcutil/method.go
index ec62b4775e..683d1955c6 100644
--- a/vendor/google.golang.org/grpc/internal/grpcutil/method.go
+++ b/vendor/google.golang.org/grpc/internal/grpcutil/method.go
@@ -39,7 +39,7 @@ func ParseMethod(methodName string) (service, method string, _ error) {
 }
 
 // baseContentType is the base content-type for gRPC.  This is a valid
-// content-type on it's own, but can also include a content-subtype such as
+// content-type on its own, but can also include a content-subtype such as
 // "proto" as a suffix after "+" or ";".  See
 // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
 // for more details.
diff --git a/vendor/google.golang.org/grpc/internal/idle/idle.go b/vendor/google.golang.org/grpc/internal/idle/idle.go
index fe49cb74c5..2c13ee9dac 100644
--- a/vendor/google.golang.org/grpc/internal/idle/idle.go
+++ b/vendor/google.golang.org/grpc/internal/idle/idle.go
@@ -182,6 +182,7 @@ func (m *Manager) tryEnterIdleMode() bool {
 	return true
 }
 
+// EnterIdleModeForTesting instructs the channel to enter idle mode.
 func (m *Manager) EnterIdleModeForTesting() {
 	m.tryEnterIdleMode()
 }
@@ -225,7 +226,7 @@ func (m *Manager) ExitIdleMode() error {
 		//   came in and OnCallBegin() noticed that the calls count is negative.
 		// - Channel is in idle mode, and multiple new RPCs come in at the same
 		//   time, all of them notice a negative calls count in OnCallBegin and get
-		//   here. The first one to get the lock would got the channel to exit idle.
+		//   here. The first one to get the lock would get the channel to exit idle.
 		// - Channel is not in idle mode, and the user calls Connect which calls
 		//   m.ExitIdleMode.
 		//
@@ -266,6 +267,7 @@ func (m *Manager) isClosed() bool {
 	return atomic.LoadInt32(&m.closed) == 1
 }
 
+// Close stops the timer associated with the Manager, if it exists.
 func (m *Manager) Close() {
 	atomic.StoreInt32(&m.closed, 1)
 
diff --git a/vendor/google.golang.org/grpc/internal/internal.go b/vendor/google.golang.org/grpc/internal/internal.go
index 7aae9240ff..20b4dc3d35 100644
--- a/vendor/google.golang.org/grpc/internal/internal.go
+++ b/vendor/google.golang.org/grpc/internal/internal.go
@@ -191,6 +191,8 @@ var (
 	// ExitIdleModeForTesting gets the ClientConn to exit IDLE mode.
 	ExitIdleModeForTesting any // func(*grpc.ClientConn) error
 
+	// ChannelzTurnOffForTesting disables the Channelz service for testing
+	// purposes.
 	ChannelzTurnOffForTesting func()
 
 	// TriggerXDSResourceNotFoundForTesting causes the provided xDS Client to
@@ -205,10 +207,6 @@ var (
 	// default resolver scheme.
 	UserSetDefaultScheme = false
 
-	// ShuffleAddressListForTesting pseudo-randomizes the order of addresses.  n
-	// is the number of elements.  swap swaps the elements with indexes i and j.
-	ShuffleAddressListForTesting any // func(n int, swap func(i, j int))
-
 	// ConnectedAddress returns the connected address for a SubConnState. The
 	// address is only valid if the state is READY.
 	ConnectedAddress any // func (scs SubConnState) resolver.Address
@@ -235,7 +233,7 @@ var (
 //
 // The implementation is expected to create a health checking RPC stream by
 // calling newStream(), watch for the health status of serviceName, and report
-// it's health back by calling setConnectivityState().
+// its health back by calling setConnectivityState().
 //
 // The health checking protocol is defined at:
 // https://github.com/grpc/grpc/blob/master/doc/health-checking.md
diff --git a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go
index 4552db16b0..374c12fb77 100644
--- a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go
+++ b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go
@@ -177,7 +177,7 @@ type dnsResolver struct {
 	// finished. Otherwise, data race will be possible. [Race Example] in
 	// dns_resolver_test we replace the real lookup functions with mocked ones to
 	// facilitate testing. If Close() doesn't wait for watcher() goroutine
-	// finishes, race detector sometimes will warns lookup (READ the lookup
+	// finishes, race detector sometimes will warn lookup (READ the lookup
 	// function pointers) inside watcher() goroutine has data race with
 	// replaceNetFunc (WRITE the lookup function pointers).
 	wg                   sync.WaitGroup
@@ -237,7 +237,9 @@ func (d *dnsResolver) watcher() {
 }
 
 func (d *dnsResolver) lookupSRV(ctx context.Context) ([]resolver.Address, error) {
-	if !EnableSRVLookups {
+	// Skip this particular host to avoid timeouts with some versions of
+	// systemd-resolved.
+	if !EnableSRVLookups || d.host == "metadata.google.internal." {
 		return nil, nil
 	}
 	var newAddrs []resolver.Address
diff --git a/vendor/google.golang.org/grpc/internal/stats/metrics_recorder_list.go b/vendor/google.golang.org/grpc/internal/stats/metrics_recorder_list.go
index be110d41f9..79044657be 100644
--- a/vendor/google.golang.org/grpc/internal/stats/metrics_recorder_list.go
+++ b/vendor/google.golang.org/grpc/internal/stats/metrics_recorder_list.go
@@ -54,6 +54,8 @@ func verifyLabels(desc *estats.MetricDescriptor, labelsRecv ...string) {
 	}
 }
 
+// RecordInt64Count records the measurement alongside labels on the int
+// count associated with the provided handle.
 func (l *MetricsRecorderList) RecordInt64Count(handle *estats.Int64CountHandle, incr int64, labels ...string) {
 	verifyLabels(handle.Descriptor(), labels...)
 
@@ -62,6 +64,8 @@ func (l *MetricsRecorderList) RecordInt64Count(handle *estats.Int64CountHandle,
 	}
 }
 
+// RecordFloat64Count records the measurement alongside labels on the float
+// count associated with the provided handle.
 func (l *MetricsRecorderList) RecordFloat64Count(handle *estats.Float64CountHandle, incr float64, labels ...string) {
 	verifyLabels(handle.Descriptor(), labels...)
 
@@ -70,6 +74,8 @@ func (l *MetricsRecorderList) RecordFloat64Count(handle *estats.Float64CountHand
 	}
 }
 
+// RecordInt64Histo records the measurement alongside labels on the int
+// histo associated with the provided handle.
 func (l *MetricsRecorderList) RecordInt64Histo(handle *estats.Int64HistoHandle, incr int64, labels ...string) {
 	verifyLabels(handle.Descriptor(), labels...)
 
@@ -78,6 +84,8 @@ func (l *MetricsRecorderList) RecordInt64Histo(handle *estats.Int64HistoHandle,
 	}
 }
 
+// RecordFloat64Histo records the measurement alongside labels on the float
+// histo associated with the provided handle.
 func (l *MetricsRecorderList) RecordFloat64Histo(handle *estats.Float64HistoHandle, incr float64, labels ...string) {
 	verifyLabels(handle.Descriptor(), labels...)
 
@@ -86,6 +94,8 @@ func (l *MetricsRecorderList) RecordFloat64Histo(handle *estats.Float64HistoHand
 	}
 }
 
+// RecordInt64Gauge records the measurement alongside labels on the int
+// gauge associated with the provided handle.
 func (l *MetricsRecorderList) RecordInt64Gauge(handle *estats.Int64GaugeHandle, incr int64, labels ...string) {
 	verifyLabels(handle.Descriptor(), labels...)
 
diff --git a/vendor/google.golang.org/grpc/internal/status/status.go b/vendor/google.golang.org/grpc/internal/status/status.go
index 757925381f..1186f1e9a9 100644
--- a/vendor/google.golang.org/grpc/internal/status/status.go
+++ b/vendor/google.golang.org/grpc/internal/status/status.go
@@ -149,6 +149,8 @@ func (s *Status) WithDetails(details ...protoadapt.MessageV1) (*Status, error) {
 
 // Details returns a slice of details messages attached to the status.
 // If a detail cannot be decoded, the error is returned in place of the detail.
+// If the detail can be decoded, the proto message returned is of the same
+// type that was given to WithDetails().
 func (s *Status) Details() []any {
 	if s == nil || s.s == nil {
 		return nil
@@ -160,7 +162,38 @@ func (s *Status) Details() []any {
 			details = append(details, err)
 			continue
 		}
-		details = append(details, detail)
+		// The call to MessageV1Of is required to unwrap the proto message if
+		// it implemented only the MessageV1 API. The proto message would have
+		// been wrapped in a V2 wrapper in Status.WithDetails. V2 messages are
+		// added to a global registry used by any.UnmarshalNew().
+		// MessageV1Of has the following behaviour:
+		// 1. If the given message is a wrapped MessageV1, it returns the
+		//   unwrapped value.
+		// 2. If the given message already implements MessageV1, it returns it
+		//   as is.
+		// 3. Else, it wraps the MessageV2 in a MessageV1 wrapper.
+		//
+		// Since the Status.WithDetails() API only accepts MessageV1, calling
+		// MessageV1Of ensures we return the same type that was given to
+		// WithDetails:
+		// * If the give type implemented only MessageV1, the unwrapping from
+		//   point 1 above will restore the type.
+		// * If the given type implemented both MessageV1 and MessageV2, point 2
+		//   above will ensure no wrapping is performed.
+		// * If the given type implemented only MessageV2 and was wrapped using
+		//   MessageV1Of before passing to WithDetails(), it would be unwrapped
+		//   in WithDetails by calling MessageV2Of(). Point 3 above will ensure
+		//   that the type is wrapped in a MessageV1 wrapper again before
+		//   returning. Note that protoc-gen-go doesn't generate code which
+		//   implements ONLY MessageV2 at the time of writing.
+		//
+		// NOTE: Status details can also be added using the FromProto method.
+		// This could theoretically allow passing a Detail message that only
+		// implements the V2 API. In such a case the message will be wrapped in
+		// a MessageV1 wrapper when fetched using Details().
+		// Since protoc-gen-go generates only code that implements both V1 and
+		// V2 APIs for backward compatibility, this is not a concern.
+		details = append(details, protoadapt.MessageV1Of(detail))
 	}
 	return details
 }
diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go
index c769deab53..62b81885d8 100644
--- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go
+++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go
@@ -86,9 +86,9 @@ type http2Client struct {
 	writerDone chan struct{} // sync point to enable testing.
 	// goAway is closed to notify the upper layer (i.e., addrConn.transportMonitor)
 	// that the server sent GoAway on this transport.
-	goAway chan struct{}
-
-	framer *framer
+	goAway        chan struct{}
+	keepaliveDone chan struct{} // Closed when the keepalive goroutine exits.
+	framer        *framer
 	// controlBuf delivers all the control related tasks (e.g., window
 	// updates, reset streams, and various settings) to the controller.
 	// Do not access controlBuf with mu held.
@@ -335,6 +335,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
 		readerDone:            make(chan struct{}),
 		writerDone:            make(chan struct{}),
 		goAway:                make(chan struct{}),
+		keepaliveDone:         make(chan struct{}),
 		framer:                newFramer(conn, writeBufSize, readBufSize, opts.SharedWriteBuffer, maxHeaderListSize),
 		fc:                    &trInFlow{limit: uint32(icwz)},
 		scheme:                scheme,
@@ -527,8 +528,9 @@ func (t *http2Client) getPeer() *peer.Peer {
 // to be the last frame loopy writes to the transport.
 func (t *http2Client) outgoingGoAwayHandler(g *goAway) (bool, error) {
 	t.mu.Lock()
-	defer t.mu.Unlock()
-	if err := t.framer.fr.WriteGoAway(t.nextID-2, http2.ErrCodeNo, g.debugData); err != nil {
+	maxStreamID := t.nextID - 2
+	t.mu.Unlock()
+	if err := t.framer.fr.WriteGoAway(maxStreamID, http2.ErrCodeNo, g.debugData); err != nil {
 		return false, err
 	}
 	return false, g.closeConn
@@ -1008,6 +1010,9 @@ func (t *http2Client) Close(err error) {
 		// should unblock it so that the goroutine eventually exits.
 		t.kpDormancyCond.Signal()
 	}
+	// Append info about previous goaways if there were any, since this may be important
+	// for understanding the root cause for this connection to be closed.
+	goAwayDebugMessage := t.goAwayDebugMessage
 	t.mu.Unlock()
 
 	// Per HTTP/2 spec, a GOAWAY frame must be sent before closing the
@@ -1025,11 +1030,13 @@ func (t *http2Client) Close(err error) {
 	}
 	t.cancel()
 	t.conn.Close()
+	// Waits for the reader and keepalive goroutines to exit before returning to
+	// ensure all resources are cleaned up before Close can return.
+	<-t.readerDone
+	if t.keepaliveEnabled {
+		<-t.keepaliveDone
+	}
 	channelz.RemoveEntry(t.channelz.ID)
-	// Append info about previous goaways if there were any, since this may be important
-	// for understanding the root cause for this connection to be closed.
-	_, goAwayDebugMessage := t.GetGoAwayReason()
-
 	var st *status.Status
 	if len(goAwayDebugMessage) > 0 {
 		st = status.Newf(codes.Unavailable, "closing transport due to: %v, received prior goaway: %v", err, goAwayDebugMessage)
@@ -1316,11 +1323,11 @@ func (t *http2Client) handlePing(f *http2.PingFrame) {
 	t.controlBuf.put(pingAck)
 }
 
-func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
+func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) error {
 	t.mu.Lock()
 	if t.state == closing {
 		t.mu.Unlock()
-		return
+		return nil
 	}
 	if f.ErrCode == http2.ErrCodeEnhanceYourCalm && string(f.DebugData()) == "too_many_pings" {
 		// When a client receives a GOAWAY with error code ENHANCE_YOUR_CALM and debug
@@ -1332,8 +1339,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
 	id := f.LastStreamID
 	if id > 0 && id%2 == 0 {
 		t.mu.Unlock()
-		t.Close(connectionErrorf(true, nil, "received goaway with non-zero even-numbered stream id: %v", id))
-		return
+		return connectionErrorf(true, nil, "received goaway with non-zero even-numbered stream id: %v", id)
 	}
 	// A client can receive multiple GoAways from the server (see
 	// https://github.com/grpc/grpc-go/issues/1387).  The idea is that the first
@@ -1350,8 +1356,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
 		// If there are multiple GoAways the first one should always have an ID greater than the following ones.
 		if id > t.prevGoAwayID {
 			t.mu.Unlock()
-			t.Close(connectionErrorf(true, nil, "received goaway with stream id: %v, which exceeds stream id of previous goaway: %v", id, t.prevGoAwayID))
-			return
+			return connectionErrorf(true, nil, "received goaway with stream id: %v, which exceeds stream id of previous goaway: %v", id, t.prevGoAwayID)
 		}
 	default:
 		t.setGoAwayReason(f)
@@ -1375,8 +1380,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
 	t.prevGoAwayID = id
 	if len(t.activeStreams) == 0 {
 		t.mu.Unlock()
-		t.Close(connectionErrorf(true, nil, "received goaway and there are no active streams"))
-		return
+		return connectionErrorf(true, nil, "received goaway and there are no active streams")
 	}
 
 	streamsToClose := make([]*Stream, 0)
@@ -1393,6 +1397,7 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
 	for _, stream := range streamsToClose {
 		t.closeStream(stream, errStreamDrain, false, http2.ErrCodeNo, statusGoAway, nil, false)
 	}
+	return nil
 }
 
 // setGoAwayReason sets the value of t.goAwayReason based
@@ -1628,7 +1633,13 @@ func (t *http2Client) readServerPreface() error {
 // network connection.  If the server preface is not read successfully, an
 // error is pushed to errCh; otherwise errCh is closed with no error.
 func (t *http2Client) reader(errCh chan<- error) {
-	defer close(t.readerDone)
+	var errClose error
+	defer func() {
+		close(t.readerDone)
+		if errClose != nil {
+			t.Close(errClose)
+		}
+	}()
 
 	if err := t.readServerPreface(); err != nil {
 		errCh <- err
@@ -1669,7 +1680,7 @@ func (t *http2Client) reader(errCh chan<- error) {
 				continue
 			}
 			// Transport error.
-			t.Close(connectionErrorf(true, err, "error reading from server: %v", err))
+			errClose = connectionErrorf(true, err, "error reading from server: %v", err)
 			return
 		}
 		switch frame := frame.(type) {
@@ -1684,7 +1695,7 @@ func (t *http2Client) reader(errCh chan<- error) {
 		case *http2.PingFrame:
 			t.handlePing(frame)
 		case *http2.GoAwayFrame:
-			t.handleGoAway(frame)
+			errClose = t.handleGoAway(frame)
 		case *http2.WindowUpdateFrame:
 			t.handleWindowUpdate(frame)
 		default:
@@ -1697,6 +1708,13 @@ func (t *http2Client) reader(errCh chan<- error) {
 
 // keepalive running in a separate goroutine makes sure the connection is alive by sending pings.
 func (t *http2Client) keepalive() {
+	var err error
+	defer func() {
+		close(t.keepaliveDone)
+		if err != nil {
+			t.Close(err)
+		}
+	}()
 	p := &ping{data: [8]byte{}}
 	// True iff a ping has been sent, and no data has been received since then.
 	outstandingPing := false
@@ -1720,7 +1738,7 @@ func (t *http2Client) keepalive() {
 				continue
 			}
 			if outstandingPing && timeoutLeft <= 0 {
-				t.Close(connectionErrorf(true, nil, "keepalive ping failed to receive ACK within timeout"))
+				err = connectionErrorf(true, nil, "keepalive ping failed to receive ACK within timeout")
 				return
 			}
 			t.mu.Lock()
diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go
index fdd6fa86cc..e12cb0bc91 100644
--- a/vendor/google.golang.org/grpc/internal/transport/transport.go
+++ b/vendor/google.golang.org/grpc/internal/transport/transport.go
@@ -547,6 +547,15 @@ func (s *Stream) write(m recvMsg) {
 	s.buf.put(m)
 }
 
+// ReadHeader reads data into the provided header slice from the stream. It
+// first checks if there was an error during a previous read operation and
+// returns it if present. It then requests a read operation for the length of
+// the header. It continues to read from the stream until the entire header
+// slice is filled or an error occurs. If an `io.EOF` error is encountered
+// with partially read data, it is converted to `io.ErrUnexpectedEOF` to
+// indicate an unexpected end of the stream. The method returns any error
+// encountered during the read process or nil if the header was successfully
+// read.
 func (s *Stream) ReadHeader(header []byte) (err error) {
 	// Don't request a read if there was an error earlier
 	if er := s.trReader.er; er != nil {
@@ -616,7 +625,7 @@ func (t *transportReader) ReadHeader(header []byte) (int, error) {
 		t.er = err
 		return 0, err
 	}
-	t.windowHandler(len(header))
+	t.windowHandler(n)
 	return n, nil
 }
 
diff --git a/vendor/google.golang.org/grpc/mem/buffers.go b/vendor/google.golang.org/grpc/mem/buffers.go
index 4d66b2ccc2..ecbf0b9a73 100644
--- a/vendor/google.golang.org/grpc/mem/buffers.go
+++ b/vendor/google.golang.org/grpc/mem/buffers.go
@@ -65,6 +65,9 @@ var (
 	refObjectPool    = sync.Pool{New: func() any { return new(atomic.Int32) }}
 )
 
+// IsBelowBufferPoolingThreshold returns true if the given size is less than or
+// equal to the threshold for buffer pooling. This is used to determine whether
+// to pool buffers or allocate them directly.
 func IsBelowBufferPoolingThreshold(size int) bool {
 	return size <= bufferPoolingThreshold
 }
@@ -89,7 +92,11 @@ func newBuffer() *buffer {
 //
 // Note that the backing array of the given data is not copied.
 func NewBuffer(data *[]byte, pool BufferPool) Buffer {
-	if pool == nil || IsBelowBufferPoolingThreshold(len(*data)) {
+	// Use the buffer's capacity instead of the length, otherwise buffers may
+	// not be reused under certain conditions. For example, if a large buffer
+	// is acquired from the pool, but fewer bytes than the buffering threshold
+	// are written to it, the buffer will not be returned to the pool.
+	if pool == nil || IsBelowBufferPoolingThreshold(cap(*data)) {
 		return (SliceBuffer)(*data)
 	}
 	b := newBuffer()
@@ -194,19 +201,19 @@ func (b *buffer) read(buf []byte) (int, Buffer) {
 	return n, b
 }
 
-// String returns a string representation of the buffer. May be used for
-// debugging purposes.
 func (b *buffer) String() string {
 	return fmt.Sprintf("mem.Buffer(%p, data: %p, length: %d)", b, b.ReadOnlyData(), len(b.ReadOnlyData()))
 }
 
+// ReadUnsafe reads bytes from the given Buffer into the provided slice.
+// It does not perform safety checks.
 func ReadUnsafe(dst []byte, buf Buffer) (int, Buffer) {
 	return buf.read(dst)
 }
 
 // SplitUnsafe modifies the receiver to point to the first n bytes while it
-// returns a new reference to the remaining bytes. The returned Buffer functions
-// just like a normal reference acquired using Ref().
+// returns a new reference to the remaining bytes. The returned Buffer
+// functions just like a normal reference acquired using Ref().
 func SplitUnsafe(buf Buffer, n int) (left, right Buffer) {
 	return buf.split(n)
 }
@@ -232,12 +239,21 @@ func (e emptyBuffer) read([]byte) (int, Buffer) {
 	return 0, e
 }
 
+// SliceBuffer is a Buffer implementation that wraps a byte slice. It provides
+// methods for reading, splitting, and managing the byte slice.
 type SliceBuffer []byte
 
+// ReadOnlyData returns the byte slice.
 func (s SliceBuffer) ReadOnlyData() []byte { return s }
-func (s SliceBuffer) Ref()                 {}
-func (s SliceBuffer) Free()                {}
-func (s SliceBuffer) Len() int             { return len(s) }
+
+// Ref is a noop implementation of Ref.
+func (s SliceBuffer) Ref() {}
+
+// Free is a noop implementation of Free.
+func (s SliceBuffer) Free() {}
+
+// Len is a noop implementation of Len.
+func (s SliceBuffer) Len() int { return len(s) }
 
 func (s SliceBuffer) split(n int) (left, right Buffer) {
 	return s[:n], s[n:]
diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go
index 2d96f1405e..aba1ae3e67 100644
--- a/vendor/google.golang.org/grpc/rpc_util.go
+++ b/vendor/google.golang.org/grpc/rpc_util.go
@@ -791,9 +791,8 @@ func checkRecvPayload(pf payloadFormat, recvCompress string, haveCompressor bool
 		if !haveCompressor {
 			if isServer {
 				return status.Newf(codes.Unimplemented, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress)
-			} else {
-				return status.Newf(codes.Internal, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress)
 			}
+			return status.Newf(codes.Internal, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress)
 		}
 	default:
 		return status.Newf(codes.Internal, "grpc: received unexpected payload format %d", pf)
diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go
index 187fbf1195..5a47094ae8 100644
--- a/vendor/google.golang.org/grpc/version.go
+++ b/vendor/google.golang.org/grpc/version.go
@@ -19,4 +19,4 @@
 package grpc
 
 // Version is the current grpc version.
-const Version = "1.67.0"
+const Version = "1.68.1"
diff --git a/vendor/modules.txt b/vendor/modules.txt
index ba869918ca..a8c7737943 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -155,8 +155,8 @@ github.com/containers/image/v5/version
 # github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01
 ## explicit
 github.com/containers/libtrust
-# github.com/containers/ocicrypt v1.2.0
-## explicit; go 1.21
+# github.com/containers/ocicrypt v1.2.1
+## explicit; go 1.22
 github.com/containers/ocicrypt
 github.com/containers/ocicrypt/blockcipher
 github.com/containers/ocicrypt/config
@@ -526,6 +526,10 @@ github.com/sirupsen/logrus
 # github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
 ## explicit
 github.com/skratchdot/open-golang/open
+# github.com/smallstep/pkcs7 v0.1.1
+## explicit; go 1.14
+github.com/smallstep/pkcs7
+github.com/smallstep/pkcs7/internal/legacy/x509
 # github.com/spf13/cobra v1.8.1
 ## explicit; go 1.15
 github.com/spf13/cobra
@@ -585,9 +589,6 @@ go.mongodb.org/mongo-driver/bson/bsonrw
 go.mongodb.org/mongo-driver/bson/bsontype
 go.mongodb.org/mongo-driver/bson/primitive
 go.mongodb.org/mongo-driver/x/bsonx/bsoncore
-# go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352
-## explicit; go 1.11
-go.mozilla.org/pkcs7
 # go.opencensus.io v0.24.0
 ## explicit; go 1.13
 go.opencensus.io
@@ -624,9 +625,11 @@ go.opentelemetry.io/otel/metric/embedded
 ## explicit; go 1.21
 go.opentelemetry.io/otel/trace
 go.opentelemetry.io/otel/trace/embedded
-# golang.org/x/crypto v0.29.0
+# golang.org/x/crypto v0.30.0
 ## explicit; go 1.20
 golang.org/x/crypto/cast5
+golang.org/x/crypto/cryptobyte
+golang.org/x/crypto/cryptobyte/asn1
 golang.org/x/crypto/internal/alias
 golang.org/x/crypto/internal/poly1305
 golang.org/x/crypto/nacl/secretbox
@@ -659,7 +662,7 @@ golang.org/x/net/trace
 ## explicit; go 1.18
 golang.org/x/oauth2
 golang.org/x/oauth2/internal
-# golang.org/x/sync v0.9.0
+# golang.org/x/sync v0.10.0
 ## explicit; go 1.18
 golang.org/x/sync/errgroup
 golang.org/x/sync/semaphore
@@ -673,7 +676,7 @@ golang.org/x/sys/windows/registry
 # golang.org/x/term v0.27.0
 ## explicit; go 1.18
 golang.org/x/term
-# golang.org/x/text v0.20.0
+# golang.org/x/text v0.21.0
 ## explicit; go 1.18
 golang.org/x/text/secure/bidirule
 golang.org/x/text/transform
@@ -682,8 +685,8 @@ golang.org/x/text/unicode/norm
 # google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1
 ## explicit; go 1.21
 google.golang.org/genproto/googleapis/rpc/status
-# google.golang.org/grpc v1.67.0
-## explicit; go 1.21
+# google.golang.org/grpc v1.68.1
+## explicit; go 1.22
 google.golang.org/grpc
 google.golang.org/grpc/attributes
 google.golang.org/grpc/backoff
@@ -691,6 +694,8 @@ google.golang.org/grpc/balancer
 google.golang.org/grpc/balancer/base
 google.golang.org/grpc/balancer/grpclb/state
 google.golang.org/grpc/balancer/pickfirst
+google.golang.org/grpc/balancer/pickfirst/internal
+google.golang.org/grpc/balancer/pickfirst/pickfirstleaf
 google.golang.org/grpc/balancer/roundrobin
 google.golang.org/grpc/binarylog/grpc_binarylog_v1
 google.golang.org/grpc/channelz