diff --git a/go.mod b/go.mod index 723a2510f..48ecf2496 100644 --- a/go.mod +++ b/go.mod @@ -37,12 +37,12 @@ require ( go.uber.org/automaxprocs v1.6.0 go.uber.org/zap v1.27.0 go.uber.org/zap/exp v0.3.0 - golang.org/x/crypto v0.41.0 - golang.org/x/crypto/x509roots/fallback v0.0.0-20250305170421-49bf5b80c810 - golang.org/x/net v0.43.0 - golang.org/x/sync v0.16.0 - golang.org/x/term v0.34.0 - golang.org/x/time v0.12.0 + golang.org/x/crypto v0.42.0 + golang.org/x/crypto/x509roots/fallback v0.0.0-20250927194341-2beaa59a3c99 + golang.org/x/net v0.44.0 + golang.org/x/sync v0.17.0 + golang.org/x/term v0.35.0 + golang.org/x/time v0.13.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 gopkg.in/yaml.v3 v3.0.1 ) @@ -90,11 +90,11 @@ require ( go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 // indirect go.opentelemetry.io/contrib/propagators/ot v1.38.0 // indirect go.uber.org/mock v0.5.2 // indirect - golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect + golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 // indirect golang.org/x/oauth2 v0.30.0 // indirect google.golang.org/api v0.247.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251002232023-7c0ddcbb5797 // indirect google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 // indirect ) @@ -153,11 +153,11 @@ require ( go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.step.sm/crypto v0.70.0 go.uber.org/multierr v1.11.0 // indirect - golang.org/x/mod v0.26.0 // indirect - golang.org/x/sys v0.35.0 - golang.org/x/text v0.28.0 // indirect - golang.org/x/tools v0.35.0 // indirect - google.golang.org/grpc v1.75.0 // indirect - google.golang.org/protobuf v1.36.8 // indirect + golang.org/x/mod v0.27.0 // indirect + golang.org/x/sys v0.36.0 + golang.org/x/text v0.29.0 // indirect + golang.org/x/tools v0.36.0 // indirect + google.golang.org/grpc v1.75.1 // indirect + google.golang.org/protobuf v1.36.10 // indirect howett.net/plist v1.0.0 // indirect ) diff --git a/go.sum b/go.sum index 91987b52d..5e7ecf73d 100644 --- a/go.sum +++ b/go.sum @@ -502,13 +502,13 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= -golang.org/x/crypto/x509roots/fallback v0.0.0-20250305170421-49bf5b80c810 h1:V5+zy0jmgNYmK1uW/sPpBw8ioFvalrhaUrYWmu1Fpe4= -golang.org/x/crypto/x509roots/fallback v0.0.0-20250305170421-49bf5b80c810/go.mod h1:lxN5T34bK4Z/i6cMaU7frUU57VkDXFD4Kamfl/cp9oU= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/crypto/x509roots/fallback v0.0.0-20250927194341-2beaa59a3c99 h1:CH0o4/bZX6KIUCjjgjmtNtfM/kXSkTYlzTOB9vZF45g= +golang.org/x/crypto/x509roots/fallback v0.0.0-20250927194341-2beaa59a3c99/go.mod h1:MEIPiCnxvQEjA4astfaKItNwEVZA5Ki+3+nyGbJ5N18= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= -golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= +golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 h1:SbTAbRFnd5kjQXbczszQ0hdk3ctwYf3qBNH9jIsGclE= +golang.org/x/exp v0.0.0-20250813145105-42675adae3e6/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -517,8 +517,8 @@ 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.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg= -golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= +golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= +golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -535,8 +535,8 @@ 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.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -556,8 +556,8 @@ 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.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -582,8 +582,8 @@ 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.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 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= @@ -594,8 +594,8 @@ 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.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -607,12 +607,12 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= -golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= +golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -623,8 +623,8 @@ 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.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= -golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= +golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= +golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= @@ -646,18 +646,18 @@ google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuO google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251002232023-7c0ddcbb5797 h1:CirRxTOwnRWVLKzDNrs0CXAaVozJoR4G9xvdRecrdpk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251002232023-7c0ddcbb5797/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= -google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= +google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/modules/caddyhttp/caddyauth/argon2id.go b/modules/caddyhttp/caddyauth/argon2id.go new file mode 100644 index 000000000..f1070ce48 --- /dev/null +++ b/modules/caddyhttp/caddyauth/argon2id.go @@ -0,0 +1,188 @@ +// Copyright 2015 Matthew Holt and The Caddy 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 caddyauth + +import ( + "crypto/rand" + "crypto/subtle" + "encoding/base64" + "fmt" + "strconv" + "strings" + + "golang.org/x/crypto/argon2" + + "github.com/caddyserver/caddy/v2" +) + +func init() { + caddy.RegisterModule(Argon2idHash{}) +} + +const ( + argon2idName = "argon2id" + defaultArgon2idTime = 1 + defaultArgon2idMemory = 46 * 1024 + defaultArgon2idThreads = 1 + defaultArgon2idKeylen = 32 + defaultSaltLength = 16 +) + +// Argon2idHash implements the Argon2id password hashing. +type Argon2idHash struct { + salt []byte + time uint32 + memory uint32 + threads uint8 + keyLen uint32 +} + +// CaddyModule returns the Caddy module information. +func (Argon2idHash) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + ID: "http.authentication.hashes.argon2id", + New: func() caddy.Module { return new(Argon2idHash) }, + } +} + +// Compare checks if the plaintext password matches the given Argon2id hash. +func (Argon2idHash) Compare(hashed, plaintext []byte) (bool, error) { + argHash, storedKey, err := DecodeHash(hashed) + if err != nil { + return false, err + } + + computedKey := argon2.IDKey( + plaintext, + argHash.salt, + argHash.time, + argHash.memory, + argHash.threads, + argHash.keyLen, + ) + + return subtle.ConstantTimeCompare(storedKey, computedKey) == 1, nil +} + +// Hash generates an Argon2id hash of the given plaintext using the configured parameters and salt. +func (b Argon2idHash) Hash(plaintext []byte) ([]byte, error) { + if b.salt == nil { + s, err := generateSalt(defaultSaltLength) + if err != nil { + return nil, err + } + b.salt = s + } + + key := argon2.IDKey( + plaintext, + b.salt, + b.time, + b.memory, + b.threads, + b.keyLen, + ) + + hash := fmt.Sprintf( + "$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s", + argon2.Version, + b.memory, + b.time, + b.threads, + base64.RawStdEncoding.EncodeToString(b.salt), + base64.RawStdEncoding.EncodeToString(key), + ) + + return []byte(hash), nil +} + +// DecodeHash parses an Argon2id PHC string into an Argon2idHash struct and returns the struct along with the derived key. +func DecodeHash(hash []byte) (*Argon2idHash, []byte, error) { + parts := strings.Split(string(hash), "$") + if len(parts) != 6 { + return nil, nil, fmt.Errorf("invalid hash format") + } + + if parts[1] != argon2idName { + return nil, nil, fmt.Errorf("unsupported variant: %s", parts[1]) + } + + version, err := strconv.Atoi(strings.TrimPrefix(parts[2], "v=")) + if err != nil { + return nil, nil, fmt.Errorf("invalid version: %w", err) + } + if version != argon2.Version { + return nil, nil, fmt.Errorf("incompatible version: %d", version) + } + + params := strings.Split(parts[3], ",") + if len(params) != 3 { + return nil, nil, fmt.Errorf("invalid parameters") + } + + mem, err := strconv.ParseUint(strings.TrimPrefix(params[0], "m="), 10, 32) + if err != nil { + return nil, nil, fmt.Errorf("invalid memory parameter: %w", err) + } + + iter, err := strconv.ParseUint(strings.TrimPrefix(params[1], "t="), 10, 32) + if err != nil { + return nil, nil, fmt.Errorf("invalid iterations parameter: %w", err) + } + + threads, err := strconv.ParseUint(strings.TrimPrefix(params[2], "p="), 10, 8) + if err != nil { + return nil, nil, fmt.Errorf("invalid parallelism parameter: %w", err) + } + + salt, err := base64.RawStdEncoding.Strict().DecodeString(parts[4]) + if err != nil { + return nil, nil, fmt.Errorf("decode salt: %w", err) + } + + key, err := base64.RawStdEncoding.Strict().DecodeString(parts[5]) + if err != nil { + return nil, nil, fmt.Errorf("decode key: %w", err) + } + + return &Argon2idHash{ + salt: salt, + time: uint32(iter), + memory: uint32(mem), + threads: uint8(threads), + keyLen: uint32(len(key)), + }, key, nil +} + +// FakeHash returns a constant fake hash for timing attacks mitigation. +func (Argon2idHash) FakeHash() []byte { + // hashed with the following command: + // caddy hash-password --plaintext "antitiming" --algorithm "argon2id" + return []byte("$argon2id$v=19$m=47104,t=1,p=1$P2nzckEdTZ3bxCiBCkRTyA$xQL3Z32eo5jKl7u5tcIsnEKObYiyNZQQf5/4sAau6Pg") +} + +// Interface guards +var ( + _ Comparer = (*Argon2idHash)(nil) + _ Hasher = (*Argon2idHash)(nil) +) + +func generateSalt(length int) ([]byte, error) { + salt := make([]byte, length) + if _, err := rand.Read(salt); err != nil { + return nil, fmt.Errorf("failed to generate salt: %w", err) + } + return salt, nil +} diff --git a/modules/caddyhttp/caddyauth/hashes.go b/modules/caddyhttp/caddyauth/bcrypt.go similarity index 97% rename from modules/caddyhttp/caddyauth/hashes.go rename to modules/caddyhttp/caddyauth/bcrypt.go index ea91f24e2..f6940996e 100644 --- a/modules/caddyhttp/caddyauth/hashes.go +++ b/modules/caddyhttp/caddyauth/bcrypt.go @@ -27,7 +27,10 @@ func init() { } // defaultBcryptCost cost 14 strikes a solid balance between security, usability, and hardware performance -const defaultBcryptCost = 14 +const ( + bcryptName = "bcrypt" + defaultBcryptCost = 14 +) // BcryptHash implements the bcrypt hash. type BcryptHash struct { diff --git a/modules/caddyhttp/caddyauth/caddyfile.go b/modules/caddyhttp/caddyauth/caddyfile.go index cc92477e5..99a33aff5 100644 --- a/modules/caddyhttp/caddyauth/caddyfile.go +++ b/modules/caddyhttp/caddyauth/caddyfile.go @@ -51,7 +51,7 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) var hashName string switch len(args) { case 0: - hashName = "bcrypt" + hashName = bcryptName case 1: hashName = args[0] case 2: @@ -62,8 +62,10 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) } switch hashName { - case "bcrypt": + case bcryptName: cmp = BcryptHash{} + case argon2idName: + cmp = Argon2idHash{} default: return nil, h.Errf("unrecognized hash algorithm: %s", hashName) } diff --git a/modules/caddyhttp/caddyauth/command.go b/modules/caddyhttp/caddyauth/command.go index 2acaee6c4..e9c513005 100644 --- a/modules/caddyhttp/caddyauth/command.go +++ b/modules/caddyhttp/caddyauth/command.go @@ -32,28 +32,55 @@ import ( func init() { caddycmd.RegisterCommand(caddycmd.Command{ Name: "hash-password", - Usage: "[--plaintext ] [--algorithm ] [--bcrypt-cost ]", + Usage: "[--plaintext ] [--algorithm ] [--bcrypt-cost ] [--argon2id-time ] [--argon2id-memory ] [--argon2id-threads ] [--argon2id-keylen ]", Short: "Hashes a password and writes base64", Long: ` Convenient way to hash a plaintext password. The resulting hash is written to stdout as a base64 string. ---plaintext, when omitted, will be read from stdin. If -Caddy is attached to a controlling tty, the plaintext will -not be echoed. +--plaintext + The password to hash. If omitted, it will be read from stdin. + If Caddy is attached to a controlling TTY, the input will not be echoed. ---algorithm currently only supports 'bcrypt', and is the default. +--algorithm + Selects the hashing algorithm. Valid options are: + * 'argon2id' (recommended for modern security) + * 'bcrypt' (legacy, slower, configurable cost) ---bcrypt-cost sets the bcrypt hashing difficulty. -Higher values increase security by making the hash computation slower and more CPU-intensive. -If the provided cost is not within the valid range [bcrypt.MinCost, bcrypt.MaxCost], -the default value (defaultBcryptCost) will be used instead. -Note: Higher cost values can significantly degrade performance on slower systems. +bcrypt-specific parameters: + +--bcrypt-cost + Sets the bcrypt hashing difficulty. Higher values increase security by + making the hash computation slower and more CPU-intensive. + Must be within the valid range [bcrypt.MinCost, bcrypt.MaxCost]. + If omitted or invalid, the default cost is used. + +Argon2id-specific parameters: + +--argon2id-time + Number of iterations to perform. Increasing this makes + hashing slower and more resistant to brute-force attacks. + +--argon2id-memory + Amount of memory to use during hashing. + Larger values increase resistance to GPU/ASIC attacks. + +--argon2id-threads + Number of CPU threads to use. Increase for faster hashing + on multi-core systems. + +--argon2id-keylen + Length of the resulting hash in bytes. Longer keys increase + security but slightly increase storage size. `, CobraFunc: func(cmd *cobra.Command) { cmd.Flags().StringP("plaintext", "p", "", "The plaintext password") - cmd.Flags().StringP("algorithm", "a", "bcrypt", "Name of the hash algorithm") + cmd.Flags().StringP("algorithm", "a", bcryptName, "Name of the hash algorithm") cmd.Flags().Int("bcrypt-cost", defaultBcryptCost, "Bcrypt hashing cost (only used with 'bcrypt' algorithm)") + cmd.Flags().Uint32("argon2id-time", defaultArgon2idTime, "Number of iterations for Argon2id hashing. Increasing this makes the hash slower and more resistant to brute-force attacks.") + cmd.Flags().Uint32("argon2id-memory", defaultArgon2idMemory, "Memory to use in KiB for Argon2id hashing. Larger values increase resistance to GPU/ASIC attacks.") + cmd.Flags().Uint8("argon2id-threads", defaultArgon2idThreads, "Number of CPU threads to use for Argon2id hashing. Increase for faster hashing on multi-core systems.") + cmd.Flags().Uint32("argon2id-keylen", defaultArgon2idKeylen, "Length of the resulting Argon2id hash in bytes. Longer hashes increase security but slightly increase storage size.") cmd.RunE = caddycmd.WrapCommandFuncForCobra(cmdHashPassword) }, }) @@ -115,8 +142,34 @@ func cmdHashPassword(fs caddycmd.Flags) (int, error) { var hash []byte var hashString string switch algorithm { - case "bcrypt": + case bcryptName: hash, err = BcryptHash{cost: bcryptCost}.Hash(plaintext) + hashString = string(hash) + case argon2idName: + time, err := fs.GetUint32("argon2id-time") + if err != nil { + return caddy.ExitCodeFailedStartup, fmt.Errorf("failed to get argon2id time parameter: %w", err) + } + memory, err := fs.GetUint32("argon2id-memory") + if err != nil { + return caddy.ExitCodeFailedStartup, fmt.Errorf("failed to get argon2id memory parameter: %w", err) + } + threads, err := fs.GetUint8("argon2id-threads") + if err != nil { + return caddy.ExitCodeFailedStartup, fmt.Errorf("failed to get argon2id threads parameter: %w", err) + } + keyLen, err := fs.GetUint32("argon2id-keylen") + if err != nil { + return caddy.ExitCodeFailedStartup, fmt.Errorf("failed to get argon2id keylen parameter: %w", err) + } + + hash, _ = Argon2idHash{ + time: time, + memory: memory, + threads: threads, + keyLen: keyLen, + }.Hash(plaintext) + hashString = string(hash) default: return caddy.ExitCodeFailedStartup, fmt.Errorf("unrecognized hash algorithm: %s", algorithm)