diff --git a/go.mod b/go.mod index 0717e9c076b9c0937874aa8e903aca16731ed4b0..43daabfc85c8d2b09fbc20c3951027d402c748f5 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ module git.autistici.org/id/auth -go 1.21.0 +go 1.23.0 -toolchain go1.22.1 +toolchain go1.24.1 require ( git.autistici.org/ai3/go-common v0.0.0-20250125130542-62b40adde91d @@ -12,7 +12,7 @@ require ( github.com/coreos/go-systemd/v22 v22.5.0 github.com/go-ldap/ldap/v3 v3.4.8 github.com/go-sql-driver/mysql v1.8.1 - github.com/go-webauthn/webauthn v0.10.2 + github.com/go-webauthn/webauthn v0.12.2 github.com/gofrs/flock v0.12.1 github.com/google/go-cmp v0.6.0 github.com/lib/pq v1.10.9 @@ -39,9 +39,9 @@ require ( github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-webauthn/x v0.1.9 // indirect + github.com/go-webauthn/x v0.1.19 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect - github.com/google/go-tpm v0.9.0 // indirect + github.com/google/go-tpm v0.9.3 // indirect github.com/google/uuid v1.6.0 // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -56,7 +56,7 @@ require ( go.opentelemetry.io/otel/exporters/zipkin v1.9.0 // indirect go.opentelemetry.io/otel/metric v0.31.0 // indirect go.opentelemetry.io/otel/sdk v1.10.0 // indirect - golang.org/x/crypto v0.27.0 // indirect - golang.org/x/sys v0.25.0 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/sys v0.31.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go.sum b/go.sum index 58c8561f6ba59137d4522981e885b45371b4f545..1723a4e8513787d3067695c7d2909951a4ac02c2 100644 --- a/go.sum +++ b/go.sum @@ -78,8 +78,12 @@ github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqw github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-webauthn/webauthn v0.10.2 h1:OG7B+DyuTytrEPFmTX503K77fqs3HDK/0Iv+z8UYbq4= github.com/go-webauthn/webauthn v0.10.2/go.mod h1:Gd1IDsGAybuvK1NkwUTLbGmeksxuRJjVN2PE/xsPxHs= +github.com/go-webauthn/webauthn v0.12.2 h1:yLaNPgBUEXDQtWnOjhsGhMMCEWbXwjg/aNkC8riJQI8= +github.com/go-webauthn/webauthn v0.12.2/go.mod h1:Q8SZPPj4sZ469fNTcQXxRpzJOdb30jQrn/36FX8jilA= github.com/go-webauthn/x v0.1.9 h1:v1oeLmoaa+gPOaZqUdDentu6Rl7HkSSsmOT6gxEQHhE= github.com/go-webauthn/x v0.1.9/go.mod h1:pJNMlIMP1SU7cN8HNlKJpLEnFHCygLCvaLZ8a1xeoQA= +github.com/go-webauthn/x v0.1.19 h1:IUfdHiBRoTdujpBA/14qbrMXQ3LGzYe/PRGWdZcmudg= +github.com/go-webauthn/x v0.1.19/go.mod h1:C5arLuTQ3pVHKPw89v7CDGnqAZSZJj+4Jnr40dsn7tk= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= @@ -112,6 +116,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= +github.com/google/go-tpm v0.9.3 h1:+yx0/anQuGzi+ssRqeD6WpXjW2L/V0dItUayO0i9sRc= +github.com/google/go-tpm v0.9.3/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -240,6 +246,8 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 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= @@ -303,6 +311,8 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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= diff --git a/vendor/github.com/go-webauthn/webauthn/metadata/const.go b/vendor/github.com/go-webauthn/webauthn/metadata/const.go new file mode 100644 index 0000000000000000000000000000000000000000..76e6a332dcfca8b0fcb64aff190f66b69159c04e --- /dev/null +++ b/vendor/github.com/go-webauthn/webauthn/metadata/const.go @@ -0,0 +1,35 @@ +package metadata + +const ( + // https://secure.globalsign.com/cacert/root-r3.crt + ProductionMDSRoot = "MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpHWD9f" + + // Production MDS URL + ProductionMDSURL = "https://mds.fidoalliance.org" + + // https://mds3.fido.tools/pki/MDS3ROOT.crt + ConformanceMDSRoot = "MIICaDCCAe6gAwIBAgIPBCqih0DiJLW7+UHXx/o1MAoGCCqGSM49BAMDMGcxCzAJBgNVBAYTAlVTMRYwFAYDVQQKDA1GSURPIEFsbGlhbmNlMScwJQYDVQQLDB5GQUtFIE1ldGFkYXRhIDMgQkxPQiBST09UIEZBS0UxFzAVBgNVBAMMDkZBS0UgUm9vdCBGQUtFMB4XDTE3MDIwMTAwMDAwMFoXDTQ1MDEzMTIzNTk1OVowZzELMAkGA1UEBhMCVVMxFjAUBgNVBAoMDUZJRE8gQWxsaWFuY2UxJzAlBgNVBAsMHkZBS0UgTWV0YWRhdGEgMyBCTE9CIFJPT1QgRkFLRTEXMBUGA1UEAwwORkFLRSBSb290IEZBS0UwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASKYiz3YltC6+lmxhPKwA1WFZlIqnX8yL5RybSLTKFAPEQeTD9O6mOz+tg8wcSdnVxHzwnXiQKJwhrav70rKc2ierQi/4QUrdsPes8TEirZOkCVJurpDFbXZOgs++pa4XmjYDBeMAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQGcfeCs0Y8D+lh6U5B2xSrR74eHTAfBgNVHSMEGDAWgBQGcfeCs0Y8D+lh6U5B2xSrR74eHTAKBggqhkjOPQQDAwNoADBlAjEA/xFsgri0xubSa3y3v5ormpPqCwfqn9s0MLBAtzCIgxQ/zkzPKctkiwoPtDzI51KnAjAmeMygX2S5Ht8+e+EQnezLJBJXtnkRWY+Zt491wgt/AwSs5PHHMv5QgjELOuMxQBc=" + + // Example from https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html + ExampleMDSRoot = "MIIGGTCCBAGgAwIBAgIUdT9qLX0sVMRe8l0sLmHd3mZovQ0wDQYJKoZIhvcNAQELBQAwgZsxHzAdBgNVBAMMFkVYQU1QTEUgTURTMyBURVNUIFJPT1QxIjAgBgkqhkiG9w0BCQEWE2V4YW1wbGVAZXhhbXBsZS5jb20xFDASBgNVBAoMC0V4YW1wbGUgT1JHMRAwDgYDVQQLDAdFeGFtcGxlMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTVkxEjAQBgNVBAcMCVdha2VmaWVsZDAeFw0yMTA0MTkxMTM1MDdaFw00ODA5MDQxMTM1MDdaMIGbMR8wHQYDVQQDDBZFWEFNUExFIE1EUzMgVEVTVCBST09UMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlQGV4YW1wbGUuY29tMRQwEgYDVQQKDAtFeGFtcGxlIE9SRzEQMA4GA1UECwwHRXhhbXBsZTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1ZMRIwEAYDVQQHDAlXYWtlZmllbGQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDDjF5wyEWuhwDHsZosGdGFTCcI677rW881vV+UfW38J+K2ioFFNeGVsxbcebK6AVOiCDPFj0974IpeD9SFOhwAHoDu/LCfXdQWp8ZgQ91ULYWoW8o7NNSp01nbN9zmaO6/xKNCa0bzjmXoGqglqnP1AtRcWYvXOSKZy1rcPeDv4Dhcpdp6W72fBw0eWIqOhsrItuY2/N8ItBPiG03EX72nACq4nZJ/nAIcUbER8STSFPPzvE97TvShsi1FD8aO6l1WkR/QkreAGjMI++GbB2Qc1nN9Y/VEDbMDhQtxXQRdpFwubTjejkN9hKOtF3B71YrwIrng3V9RoPMFdapWMzSlI+WWHog0oTj1PqwJDDg7+z1I6vSDeVWAMKr9mq1w1OGNzgBopIjd9lRWkRtt2kQSPX9XxqS4E1gDDr8MKbpM3JuubQtNCg9D7Ljvbz6vwvUrbPHH+oREvucsp0PZ5PpizloepGIcLFxDQqCulGY2n7Ahl0JOFXJqOFCaK3TWHwBvZsaY5DgBuUvdUrwtgZNg2eg2omWXEepiVFQn3Fvj43Wh2npPMgIe5P0rwncXvROxaczd4rtajKS1ucoB9b9iKqM2+M1y/FDIgVf1fWEHwK7YdzxMlgOeLdeV/kqRU5PEUlLU9a2EwdOErrPbPKZmIfbs/L4B3k4zejMDH3Y+ZwIDAQABo1MwUTAdBgNVHQ4EFgQU8sWwq1TrurK7xMTwO1dKfeJBbCMwHwYDVR0jBBgwFoAU8sWwq1TrurK7xMTwO1dKfeJBbCMwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAFw6M1PiIfCPIBQ5EBUPNmRvRFuDpolOmDofnf/+mv63LqwQZAdo/W8tzZ9kOFhq24SiLw0H7fsdG/jeREXiIZMNoW/rA6Uac8sU+FYF7Q+qp6CQLlSQbDcpVMifTQjcBk2xh+aLK9SrrXBqnTAhwS+offGtAW8DpoLuH4tAcQmIjlgMlN65jnELCuqNR/wpA+zch8LZW8saQ2cwRCwdr8mAzZoLbsDSVCHxQF3/kQjPT7Nao1q2iWcY3OYcRmKrieHDP67yeLUbVmetfZis2d6ZlkqHLB4ZW1xX4otsEFkuTJA3HWDRsNyhTwx1YoCLsYut5Zp0myqPNBq28w6qGMyyoJN0Z4RzMEO3R6i/MQNfhK55/8O2HciM6xb5t/aBSuHPKlBDrFWhpRnKYkaNtlUo35qV5IbKGKau3SdZdSRciaXUd/p81YmoF01UlhhMz/Rqr1k2gyA0a9tF8+awCeanYt5izl8YO0FlrOU1SQ5UQw4szqqZqbrf4e8fRuU2TXNx4zk+ImE7WRB44f6mSD746ZCBRogZ/SA5jUBu+OPe4/sEtERWRcQD+fXgce9ZEN0+peyJIKAsl5Rm2Bmgyg5IoyWwSG5W+WekGyEokpslou2Yc6EjUj5ndZWz5EiHAiQ74hNfDoCZIxVVLU3Qbp8a0S1bmsoT2JOsspIbtZUg=" +) + +const ( + HeaderX509URI = "x5u" + HeaderX509Certificate = "x5c" +) + +var ( + errIntermediateCertRevoked = &Error{ + Type: "intermediate_revoked", + Details: "Intermediate certificate is on issuers revocation list", + } + errLeafCertRevoked = &Error{ + Type: "leaf_revoked", + Details: "Leaf certificate is on issuers revocation list", + } + errCRLUnavailable = &Error{ + Type: "crl_unavailable", + Details: "Certificate revocation list is unavailable", + } +) diff --git a/vendor/github.com/go-webauthn/webauthn/metadata/decode.go b/vendor/github.com/go-webauthn/webauthn/metadata/decode.go new file mode 100644 index 0000000000000000000000000000000000000000..7d4b35179cd72cf20b30cd39f3f9a7430468d360 --- /dev/null +++ b/vendor/github.com/go-webauthn/webauthn/metadata/decode.go @@ -0,0 +1,274 @@ +package metadata + +import ( + "crypto/x509" + "encoding/base64" + "errors" + "fmt" + "io" + "net/http" + "strings" + "time" + + "github.com/go-webauthn/x/revoke" + "github.com/golang-jwt/jwt/v5" + "github.com/mitchellh/mapstructure" +) + +// NewDecoder returns a new metadata decoder. +func NewDecoder(opts ...DecoderOption) (decoder *Decoder, err error) { + decoder = &Decoder{ + client: &http.Client{}, + parser: jwt.NewParser(), + hook: mapstructure.ComposeDecodeHookFunc(), + } + + for _, opt := range opts { + if err = opt(decoder); err != nil { + return nil, fmt.Errorf("failed to apply decoder option: %w", err) + } + } + + if decoder.root == "" { + decoder.root = ProductionMDSRoot + } + + return decoder, nil +} + +// Decoder handles decoding and specialized parsing of the metadata blob. +type Decoder struct { + client *http.Client + parser *jwt.Parser + hook mapstructure.DecodeHookFunc + root string + ignoreEntryParsingErrors bool +} + +// Parse handles parsing of the raw JSON values of the metadata blob. Should be used after using Decode or DecodeBytes. +func (d *Decoder) Parse(payload *PayloadJSON) (metadata *Metadata, err error) { + metadata = &Metadata{ + Parsed: Parsed{ + LegalHeader: payload.LegalHeader, + Number: payload.Number, + }, + } + + if metadata.Parsed.NextUpdate, err = time.Parse(time.DateOnly, payload.NextUpdate); err != nil { + return nil, fmt.Errorf("error occurred parsing next update value '%s': %w", payload.NextUpdate, err) + } + + var parsed Entry + + for _, entry := range payload.Entries { + if parsed, err = entry.Parse(); err != nil { + metadata.Unparsed = append(metadata.Unparsed, EntryError{ + Error: err, + EntryJSON: entry, + }) + + continue + } + + metadata.Parsed.Entries = append(metadata.Parsed.Entries, parsed) + } + + if n := len(metadata.Unparsed); n != 0 && !d.ignoreEntryParsingErrors { + return metadata, fmt.Errorf("error occurred parsing metadata: %d entries had errors during parsing", n) + } + + return metadata, nil +} + +// Decode the blob from an io.Reader. This function will close the io.ReadCloser after completing. +func (d *Decoder) Decode(r io.Reader) (payload *PayloadJSON, err error) { + bytes, err := io.ReadAll(r) + if err != nil { + return nil, err + } + + return d.DecodeBytes(bytes) +} + +// DecodeBytes handles decoding raw bytes. If you have a read closer it's suggested to use Decode. +func (d *Decoder) DecodeBytes(bytes []byte) (payload *PayloadJSON, err error) { + var token *jwt.Token + + if token, err = d.parser.Parse(string(bytes), func(token *jwt.Token) (any, error) { + // 2. If the x5u attribute is present in the JWT Header, then + if _, ok := token.Header[HeaderX509URI].([]any); ok { + // never seen an x5u here, although it is in the spec + return nil, errors.New("x5u encountered in header of metadata TOC payload") + } + + // 3. If the x5u attribute is missing, the chain should be retrieved from the x5c attribute. + var ( + x5c, chain []any + ok, valid bool + ) + + if x5c, ok = token.Header[HeaderX509Certificate].([]any); !ok { + // If that attribute is missing as well, Metadata TOC signing trust anchor is considered the TOC signing certificate chain. + chain = []any{d.root} + } else { + chain = x5c + } + + // The certificate chain MUST be verified to properly chain to the metadata TOC signing trust anchor. + if valid, err = validateChain(d.root, chain); !valid || err != nil { + return nil, err + } + + // Chain validated, extract the TOC signing certificate from the chain. Create a buffer large enough to hold the + // certificate bytes. + o := make([]byte, base64.StdEncoding.DecodedLen(len(chain[0].(string)))) + + var ( + n int + cert *x509.Certificate + ) + + // Decode the base64 certificate into the buffer. + if n, err = base64.StdEncoding.Decode(o, []byte(chain[0].(string))); err != nil { + return nil, err + } + + // Parse the certificate from the buffer. + if cert, err = x509.ParseCertificate(o[:n]); err != nil { + return nil, err + } + + // 4. Verify the signature of the Metadata TOC object using the TOC signing certificate chain + // jwt.Parse() uses the TOC signing certificate public key internally to verify the signature. + return cert.PublicKey, err + }); err != nil { + return nil, err + } + + var decoder *mapstructure.Decoder + + payload = &PayloadJSON{} + + if decoder, err = mapstructure.NewDecoder(&mapstructure.DecoderConfig{ + Metadata: nil, + Result: payload, + DecodeHook: d.hook, + TagName: "json", + }); err != nil { + return nil, err + } + + if err = decoder.Decode(token.Claims); err != nil { + return payload, err + } + + return payload, nil +} + +// DecoderOption is a representation of a function that can set options within a decoder. +type DecoderOption func(decoder *Decoder) (err error) + +// WithIgnoreEntryParsingErrors is a DecoderOption which ignores errors when parsing individual entries. The values for +// these entries will exist as an unparsed entry. +func WithIgnoreEntryParsingErrors() DecoderOption { + return func(decoder *Decoder) (err error) { + decoder.ignoreEntryParsingErrors = true + + return nil + } +} + +// WithRootCertificate overrides the root certificate used to validate the authenticity of the metadata payload. +func WithRootCertificate(value string) DecoderOption { + return func(decoder *Decoder) (err error) { + decoder.root = value + + return nil + } +} + +func validateChain(root string, chain []any) (bool, error) { + oRoot := make([]byte, base64.StdEncoding.DecodedLen(len(root))) + + nRoot, err := base64.StdEncoding.Decode(oRoot, []byte(root)) + if err != nil { + return false, err + } + + rootcert, err := x509.ParseCertificate(oRoot[:nRoot]) + if err != nil { + return false, err + } + + roots := x509.NewCertPool() + + roots.AddCert(rootcert) + + o := make([]byte, base64.StdEncoding.DecodedLen(len(chain[1].(string)))) + + n, err := base64.StdEncoding.Decode(o, []byte(chain[1].(string))) + if err != nil { + return false, err + } + + intcert, err := x509.ParseCertificate(o[:n]) + if err != nil { + return false, err + } + + if revoked, ok := revoke.VerifyCertificate(intcert); !ok { + issuer := intcert.IssuingCertificateURL + + if issuer != nil { + return false, errCRLUnavailable + } + } else if revoked { + return false, errIntermediateCertRevoked + } + + ints := x509.NewCertPool() + ints.AddCert(intcert) + + l := make([]byte, base64.StdEncoding.DecodedLen(len(chain[0].(string)))) + + n, err = base64.StdEncoding.Decode(l, []byte(chain[0].(string))) + if err != nil { + return false, err + } + + leafcert, err := x509.ParseCertificate(l[:n]) + if err != nil { + return false, err + } + + if revoked, ok := revoke.VerifyCertificate(leafcert); !ok { + return false, errCRLUnavailable + } else if revoked { + return false, errLeafCertRevoked + } + + opts := x509.VerifyOptions{ + Roots: roots, + Intermediates: ints, + } + + _, err = leafcert.Verify(opts) + + return err == nil, err +} + +func mdsParseX509Certificate(value string) (certificate *x509.Certificate, err error) { + var n int + + raw := make([]byte, base64.StdEncoding.DecodedLen(len(value))) + + if n, err = base64.StdEncoding.Decode(raw, []byte(strings.TrimSpace(value))); err != nil { + return nil, fmt.Errorf("error occurred parsing *x509.certificate: error occurred decoding base64 data: %w", err) + } + + if certificate, err = x509.ParseCertificate(raw[:n]); err != nil { + return nil, err + } + + return certificate, nil +} diff --git a/vendor/github.com/go-webauthn/webauthn/metadata/doc.go b/vendor/github.com/go-webauthn/webauthn/metadata/doc.go new file mode 100644 index 0000000000000000000000000000000000000000..7db8c71da3bb78c85278e32208dd2d83aebf144d --- /dev/null +++ b/vendor/github.com/go-webauthn/webauthn/metadata/doc.go @@ -0,0 +1,2 @@ +// Package metadata handles metadata validation instrumentation. +package metadata diff --git a/vendor/github.com/go-webauthn/webauthn/metadata/metadata.go b/vendor/github.com/go-webauthn/webauthn/metadata/metadata.go index af0a495047bfa8de191dd5182d8f17fc4f777a3f..d6e9183209ed4f57c1f3d4bf2cd9f419ee130fdc 100644 --- a/vendor/github.com/go-webauthn/webauthn/metadata/metadata.go +++ b/vendor/github.com/go-webauthn/webauthn/metadata/metadata.go @@ -2,533 +2,902 @@ package metadata import ( "crypto/x509" - "encoding/base64" - "errors" - "io" + "fmt" "net/http" - "reflect" + "net/url" + "strings" "time" - "github.com/golang-jwt/jwt/v5" "github.com/google/uuid" - "github.com/mitchellh/mapstructure" +) + +// Fetch creates a new HTTP client and gets the production metadata, decodes it, and parses it. This is an +// instrumentation simplification that makes it easier to either just grab the latest metadata or for implementers to +// see the rough process of retrieving it to implement any of their own logic. +func Fetch() (metadata *Metadata, err error) { + var ( + decoder *Decoder + payload *PayloadJSON + res *http.Response + ) + + if decoder, err = NewDecoder(WithIgnoreEntryParsingErrors()); err != nil { + return nil, err + } - "github.com/go-webauthn/x/revoke" + client := &http.Client{} - "github.com/go-webauthn/webauthn/protocol/webauthncose" -) + if res, err = client.Get(ProductionMDSURL); err != nil { + return nil, err + } + + if payload, err = decoder.Decode(res.Body); err != nil { + return nil, err + } -type PublicKeyCredentialParameters struct { - Type string `json:"type"` - Alg webauthncose.COSEAlgorithmIdentifier `json:"alg"` + return decoder.Parse(payload) } -const ( - // https://secure.globalsign.com/cacert/root-r3.crt - ProductionMDSRoot = "MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpHWD9f" - // Production MDS URL - ProductionMDSURL = "https://mds.fidoalliance.org" - // https://mds3.fido.tools/pki/MDS3ROOT.crt - ConformanceMDSRoot = "MIICaDCCAe6gAwIBAgIPBCqih0DiJLW7+UHXx/o1MAoGCCqGSM49BAMDMGcxCzAJBgNVBAYTAlVTMRYwFAYDVQQKDA1GSURPIEFsbGlhbmNlMScwJQYDVQQLDB5GQUtFIE1ldGFkYXRhIDMgQkxPQiBST09UIEZBS0UxFzAVBgNVBAMMDkZBS0UgUm9vdCBGQUtFMB4XDTE3MDIwMTAwMDAwMFoXDTQ1MDEzMTIzNTk1OVowZzELMAkGA1UEBhMCVVMxFjAUBgNVBAoMDUZJRE8gQWxsaWFuY2UxJzAlBgNVBAsMHkZBS0UgTWV0YWRhdGEgMyBCTE9CIFJPT1QgRkFLRTEXMBUGA1UEAwwORkFLRSBSb290IEZBS0UwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASKYiz3YltC6+lmxhPKwA1WFZlIqnX8yL5RybSLTKFAPEQeTD9O6mOz+tg8wcSdnVxHzwnXiQKJwhrav70rKc2ierQi/4QUrdsPes8TEirZOkCVJurpDFbXZOgs++pa4XmjYDBeMAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQGcfeCs0Y8D+lh6U5B2xSrR74eHTAfBgNVHSMEGDAWgBQGcfeCs0Y8D+lh6U5B2xSrR74eHTAKBggqhkjOPQQDAwNoADBlAjEA/xFsgri0xubSa3y3v5ormpPqCwfqn9s0MLBAtzCIgxQ/zkzPKctkiwoPtDzI51KnAjAmeMygX2S5Ht8+e+EQnezLJBJXtnkRWY+Zt491wgt/AwSs5PHHMv5QgjELOuMxQBc=" - // Example from https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html - ExampleMDSRoot = "MIIGGTCCBAGgAwIBAgIUdT9qLX0sVMRe8l0sLmHd3mZovQ0wDQYJKoZIhvcNAQELBQAwgZsxHzAdBgNVBAMMFkVYQU1QTEUgTURTMyBURVNUIFJPT1QxIjAgBgkqhkiG9w0BCQEWE2V4YW1wbGVAZXhhbXBsZS5jb20xFDASBgNVBAoMC0V4YW1wbGUgT1JHMRAwDgYDVQQLDAdFeGFtcGxlMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTVkxEjAQBgNVBAcMCVdha2VmaWVsZDAeFw0yMTA0MTkxMTM1MDdaFw00ODA5MDQxMTM1MDdaMIGbMR8wHQYDVQQDDBZFWEFNUExFIE1EUzMgVEVTVCBST09UMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlQGV4YW1wbGUuY29tMRQwEgYDVQQKDAtFeGFtcGxlIE9SRzEQMA4GA1UECwwHRXhhbXBsZTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1ZMRIwEAYDVQQHDAlXYWtlZmllbGQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDDjF5wyEWuhwDHsZosGdGFTCcI677rW881vV+UfW38J+K2ioFFNeGVsxbcebK6AVOiCDPFj0974IpeD9SFOhwAHoDu/LCfXdQWp8ZgQ91ULYWoW8o7NNSp01nbN9zmaO6/xKNCa0bzjmXoGqglqnP1AtRcWYvXOSKZy1rcPeDv4Dhcpdp6W72fBw0eWIqOhsrItuY2/N8ItBPiG03EX72nACq4nZJ/nAIcUbER8STSFPPzvE97TvShsi1FD8aO6l1WkR/QkreAGjMI++GbB2Qc1nN9Y/VEDbMDhQtxXQRdpFwubTjejkN9hKOtF3B71YrwIrng3V9RoPMFdapWMzSlI+WWHog0oTj1PqwJDDg7+z1I6vSDeVWAMKr9mq1w1OGNzgBopIjd9lRWkRtt2kQSPX9XxqS4E1gDDr8MKbpM3JuubQtNCg9D7Ljvbz6vwvUrbPHH+oREvucsp0PZ5PpizloepGIcLFxDQqCulGY2n7Ahl0JOFXJqOFCaK3TWHwBvZsaY5DgBuUvdUrwtgZNg2eg2omWXEepiVFQn3Fvj43Wh2npPMgIe5P0rwncXvROxaczd4rtajKS1ucoB9b9iKqM2+M1y/FDIgVf1fWEHwK7YdzxMlgOeLdeV/kqRU5PEUlLU9a2EwdOErrPbPKZmIfbs/L4B3k4zejMDH3Y+ZwIDAQABo1MwUTAdBgNVHQ4EFgQU8sWwq1TrurK7xMTwO1dKfeJBbCMwHwYDVR0jBBgwFoAU8sWwq1TrurK7xMTwO1dKfeJBbCMwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAFw6M1PiIfCPIBQ5EBUPNmRvRFuDpolOmDofnf/+mv63LqwQZAdo/W8tzZ9kOFhq24SiLw0H7fsdG/jeREXiIZMNoW/rA6Uac8sU+FYF7Q+qp6CQLlSQbDcpVMifTQjcBk2xh+aLK9SrrXBqnTAhwS+offGtAW8DpoLuH4tAcQmIjlgMlN65jnELCuqNR/wpA+zch8LZW8saQ2cwRCwdr8mAzZoLbsDSVCHxQF3/kQjPT7Nao1q2iWcY3OYcRmKrieHDP67yeLUbVmetfZis2d6ZlkqHLB4ZW1xX4otsEFkuTJA3HWDRsNyhTwx1YoCLsYut5Zp0myqPNBq28w6qGMyyoJN0Z4RzMEO3R6i/MQNfhK55/8O2HciM6xb5t/aBSuHPKlBDrFWhpRnKYkaNtlUo35qV5IbKGKau3SdZdSRciaXUd/p81YmoF01UlhhMz/Rqr1k2gyA0a9tF8+awCeanYt5izl8YO0FlrOU1SQ5UQw4szqqZqbrf4e8fRuU2TXNx4zk+ImE7WRB44f6mSD746ZCBRogZ/SA5jUBu+OPe4/sEtERWRcQD+fXgce9ZEN0+peyJIKAsl5Rm2Bmgyg5IoyWwSG5W+WekGyEokpslou2Yc6EjUj5ndZWz5EiHAiQ74hNfDoCZIxVVLU3Qbp8a0S1bmsoT2JOsspIbtZUg=" -) +type Metadata struct { + Parsed Parsed + Unparsed []EntryError +} + +func (m *Metadata) ToMap() (metadata map[uuid.UUID]*Entry) { + metadata = make(map[uuid.UUID]*Entry) -// Metadata is a map of authenticator AAGUIDs to corresponding metadata statements -var Metadata = make(map[uuid.UUID]MetadataBLOBPayloadEntry) + for _, entry := range m.Parsed.Entries { + if entry.AaGUID != uuid.Nil { + metadata[entry.AaGUID] = &entry + } + } -// Conformance indicates if test metadata is currently being used -var Conformance = false + return metadata +} -var MDSRoot = ProductionMDSRoot +// Parsed is a structure representing the Parsed MDS3 dictionary. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#metadata-blob-payload-entry-dictionary +type Parsed struct { + // The legalHeader, if present, contains a legal guide for accessing and using metadata, which itself MAY contain URL(s) pointing to further information, such as a full Terms and Conditions statement. + LegalHeader string + + // The serial number of this UAF Metadata TOC Payload. Serial numbers MUST be consecutive and strictly monotonic, i.e. the successor TOC will have a no value exactly incremented by one. + Number int + + // ISO-8601 formatted date when the next update will be provided at latest. + NextUpdate time.Time + + // List of zero or more MetadataTOCPayloadEntry objects. + Entries []Entry +} + +// PayloadJSON is an intermediary JSON/JWT representation of the Parsed. +type PayloadJSON struct { + LegalHeader string `json:"legalHeader"` + Number int `json:"no"` + NextUpdate string `json:"nextUpdate"` + + Entries []EntryJSON `json:"entries"` +} -// MetadataBLOBPayloadEntry - Represents the MetadataBLOBPayloadEntry -// https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#metadata-blob-payload-entry-dictionary -type MetadataBLOBPayloadEntry struct { +func (j PayloadJSON) Parse() (payload Parsed, err error) { + var update time.Time + + if update, err = time.Parse(time.DateOnly, j.NextUpdate); err != nil { + return payload, fmt.Errorf("error occurred parsing next update value '%s': %w", j.NextUpdate, err) + } + + n := len(j.Entries) + + entries := make([]Entry, n) + + for i := 0; i < n; i++ { + if entries[i], err = j.Entries[i].Parse(); err != nil { + return payload, fmt.Errorf("error occurred parsing entry %d: %w", i, err) + } + } + + return Parsed{ + LegalHeader: j.LegalHeader, + Number: j.Number, + NextUpdate: update, + Entries: entries, + }, nil +} + +// Entry is a structure representing the Entry MDS3 dictionary. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#metadata-blob-payload-entry-dictionary +type Entry struct { // The Authenticator Attestation ID. Aaid string `json:"aaid"` + // The Authenticator Attestation GUID. - AaGUID string `json:"aaguid"` + AaGUID uuid.UUID `json:"aaguid"` + // A list of the attestation certificate public key identifiers encoded as hex string. AttestationCertificateKeyIdentifiers []string `json:"attestationCertificateKeyIdentifiers"` + // The metadataStatement JSON object as defined in FIDOMetadataStatement. - MetadataStatement MetadataStatement `json:"metadataStatement"` + MetadataStatement Statement `json:"metadataStatement"` + // Status of the FIDO Biometric Certification of one or more biometric components of the Authenticator BiometricStatusReports []BiometricStatusReport `json:"biometricStatusReports"` + // An array of status reports applicable to this authenticator. StatusReports []StatusReport `json:"statusReports"` + // ISO-8601 formatted date since when the status report array was set to the current value. - TimeOfLastStatusChange string `json:"timeOfLastStatusChange"` + TimeOfLastStatusChange time.Time + // URL of a list of rogue (i.e. untrusted) individual authenticators. - RogueListURL string `json:"rogueListURL"` + RogueListURL *url.URL + // The hash value computed over the Base64url encoding of the UTF-8 representation of the JSON encoded rogueList available at rogueListURL (with type rogueListEntry[]). - RogueListHash string `json:"rogueListHash"` + RogueListHash string +} + +// EntryJSON is an intermediary JSON/JWT structure representing the Entry MDS3 dictionary. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#metadata-blob-payload-entry-dictionary +type EntryJSON struct { + Aaid string `json:"aaid"` + AaGUID string `json:"aaguid"` + AttestationCertificateKeyIdentifiers []string `json:"attestationCertificateKeyIdentifiers"` + + MetadataStatement StatementJSON `json:"metadataStatement"` + BiometricStatusReports []BiometricStatusReportJSON `json:"biometricStatusReports"` + StatusReports []StatusReportJSON `json:"statusReports"` + + TimeOfLastStatusChange string `json:"timeOfLastStatusChange"` + RogueListURL string `json:"rogueListURL"` + RogueListHash string `json:"rogueListHash"` +} + +func (j EntryJSON) Parse() (entry Entry, err error) { + var aaguid uuid.UUID + + if len(j.AaGUID) != 0 { + if aaguid, err = uuid.Parse(j.AaGUID); err != nil { + return entry, fmt.Errorf("error occurred parsing metadata entry with AAGUID '%s': error parsing AAGUID: %w", j.AaGUID, err) + } + } + + var statement Statement + + if statement, err = j.MetadataStatement.Parse(); err != nil { + return entry, fmt.Errorf("error occurred parsing metadata entry with AAGUID '%s': %w", j.AaGUID, err) + } + + var i, n int + + n = len(j.BiometricStatusReports) + + bsrs := make([]BiometricStatusReport, n) + + for i = 0; i < n; i++ { + if bsrs[i], err = j.BiometricStatusReports[i].Parse(); err != nil { + return entry, fmt.Errorf("error occurred parsing metadata entry with AAGUID '%s': error occurred parsing biometric status report %d: %w", j.AaGUID, i, err) + } + } + + n = len(j.StatusReports) + + srs := make([]StatusReport, n) + + for i = 0; i < n; i++ { + if srs[i], err = j.StatusReports[i].Parse(); err != nil { + return entry, fmt.Errorf("error occurred parsing metadata entry with AAGUID '%s': error occurred parsing status report %d: %w", j.AaGUID, i, err) + } + } + + var change time.Time + + if change, err = time.Parse(time.DateOnly, j.TimeOfLastStatusChange); err != nil { + return entry, fmt.Errorf("error occurred parsing metadata entry with AAGUID '%s': error occurred parsing time of last status change value: %w", j.AaGUID, err) + } + + var rogues *url.URL + + if len(j.RogueListURL) != 0 { + if rogues, err = url.ParseRequestURI(j.RogueListURL); err != nil { + return entry, fmt.Errorf("error occurred parsing metadata entry with AAGUID '%s': error occurred parsing rogue list URL value: %w", j.AaGUID, err) + } + + if len(j.RogueListHash) == 0 { + return entry, fmt.Errorf("error occurred parsing metadata entry with AAGUID '%s': error occurred validating rogue list URL value: the rogue list hash was absent", j.AaGUID) + } + } + + return Entry{ + Aaid: j.Aaid, + AaGUID: aaguid, + AttestationCertificateKeyIdentifiers: j.AttestationCertificateKeyIdentifiers, + MetadataStatement: statement, + BiometricStatusReports: bsrs, + StatusReports: srs, + TimeOfLastStatusChange: change, + RogueListURL: rogues, + RogueListHash: j.RogueListHash, + }, nil +} + +// Statement is a structure representing the Statement MDS3 dictionary. +// Authenticator metadata statements are used directly by the FIDO server at a relying party, but the information +// contained in the authoritative statement is used in several other places. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#metadata-keys +type Statement struct { + // The legalHeader, if present, contains a legal guide for accessing and using metadata, which itself MAY contain URL(s) pointing to further information, such as a full Terms and Conditions statement. + LegalHeader string + + // The Authenticator Attestation ID. + Aaid string + + // The Authenticator Attestation GUID. + AaGUID uuid.UUID + + // A list of the attestation certificate public key identifiers encoded as hex string. + AttestationCertificateKeyIdentifiers []string + + // A human-readable, short description of the authenticator, in English. + Description string + + // A list of human-readable short descriptions of the authenticator in different languages. + AlternativeDescriptions map[string]string + + // Earliest (i.e. lowest) trustworthy authenticatorVersion meeting the requirements specified in this metadata statement. + AuthenticatorVersion uint32 + + // The FIDO protocol family. The values "uaf", "u2f", and "fido2" are supported. + ProtocolFamily string + + // he Metadata Schema version. + Schema uint16 + + // The FIDO unified protocol version(s) (related to the specific protocol family) supported by this authenticator. + Upv []Version + + // The list of authentication algorithms supported by the authenticator. + AuthenticationAlgorithms []AuthenticationAlgorithm + + // The list of public key formats supported by the authenticator during registration operations. + PublicKeyAlgAndEncodings []PublicKeyAlgAndEncoding + + // The supported attestation type(s). + AttestationTypes AuthenticatorAttestationTypes + + // A list of alternative VerificationMethodANDCombinations. + UserVerificationDetails [][]VerificationMethodDescriptor + + // A 16-bit number representing the bit fields defined by the KEY_PROTECTION constants in the FIDO Registry of Predefined Values + KeyProtection []string + + // This entry is set to true or it is omitted, if the Uauth private key is restricted by the authenticator to only sign valid FIDO signature assertions. + // This entry is set to false, if the authenticator doesn't restrict the Uauth key to only sign valid FIDO signature assertions. + IsKeyRestricted bool + + // This entry is set to true or it is omitted, if Uauth key usage always requires a fresh user verification + // This entry is set to false, if the Uauth key can be used without requiring a fresh user verification, e.g. without any additional user interaction, if the user was verified a (potentially configurable) caching time ago. + IsFreshUserVerificationRequired bool + + // A 16-bit number representing the bit fields defined by the MATCHER_PROTECTION constants in the FIDO Registry of Predefined Values + MatcherProtection []string + + // The authenticator's overall claimed cryptographic strength in bits (sometimes also called security strength or security level). + CryptoStrength uint16 + + // A 32-bit number representing the bit fields defined by the ATTACHMENT_HINT constants in the FIDO Registry of Predefined Values + AttachmentHint []string + + // A 16-bit number representing a combination of the bit flags defined by the TRANSACTION_CONFIRMATION_DISPLAY constants in the FIDO Registry of Predefined Values + TcDisplay []string + + // Supported MIME content type [RFC2049] for the transaction confirmation display, such as text/plain or image/png. + TcDisplayContentType string + + // A list of alternative DisplayPNGCharacteristicsDescriptor. Each of these entries is one alternative of supported image characteristics for displaying a PNG image. + TcDisplayPNGCharacteristics []DisplayPNGCharacteristicsDescriptor + + // Each element of this array represents a PKIX [RFC5280] X.509 certificate that is a valid trust anchor for this authenticator model. + // Multiple certificates might be used for different batches of the same model. + // The array does not represent a certificate chain, but only the trust anchor of that chain. + // A trust anchor can be a root certificate, an intermediate CA certificate or even the attestation certificate itself. + AttestationRootCertificates []*x509.Certificate + + // A list of trust anchors used for ECDAA attestation. This entry MUST be present if and only if attestationType includes ATTESTATION_ECDAA. + EcdaaTrustAnchors []EcdaaTrustAnchor + + // A data: url [RFC2397] encoded PNG [PNG] icon for the Authenticator. + Icon *url.URL + + // List of extensions supported by the authenticator. + SupportedExtensions []ExtensionDescriptor + + // Describes supported versions, extensions, AAGUID of the device and its capabilities + AuthenticatorGetInfo AuthenticatorGetInfo +} + +func (s *Statement) Verifier(x5cis []*x509.Certificate) (opts x509.VerifyOptions) { + roots := x509.NewCertPool() + + for _, root := range s.AttestationRootCertificates { + roots.AddCert(root) + } + + var intermediates *x509.CertPool + + if len(x5cis) > 0 { + intermediates = x509.NewCertPool() + + for _, x5c := range x5cis { + intermediates.AddCert(x5c) + } + } + + return x509.VerifyOptions{ + Roots: roots, + Intermediates: intermediates, + } } -// https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#biometricstatusreport-dictionary -// BiometricStatusReport - Contains the current BiometricStatusReport of one of the authenticator's biometric component. +// StatementJSON is an intermediary JSON/JWT structure representing the Statement MDS3 dictionary. +// Authenticator metadata statements are used directly by the FIDO server at a relying party, but the information +// contained in the authoritative statement is used in several other places. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#metadata-keys +type StatementJSON struct { + LegalHeader string `json:"legalHeader"` + Aaid string `json:"aaid"` + AaGUID string `json:"aaguid"` + AttestationCertificateKeyIdentifiers []string `json:"attestationCertificateKeyIdentifiers"` + Description string `json:"description"` + AlternativeDescriptions map[string]string `json:"alternativeDescriptions"` + AuthenticatorVersion uint32 `json:"authenticatorVersion"` + ProtocolFamily string `json:"protocolFamily"` + Schema uint16 `json:"schema"` + Upv []Version `json:"upv"` + AuthenticationAlgorithms []AuthenticationAlgorithm `json:"authenticationAlgorithms"` + PublicKeyAlgAndEncodings []PublicKeyAlgAndEncoding `json:"publicKeyAlgAndEncodings"` + AttestationTypes []AuthenticatorAttestationType `json:"attestationTypes"` + UserVerificationDetails [][]VerificationMethodDescriptor `json:"userVerificationDetails"` + KeyProtection []string `json:"keyProtection"` + IsKeyRestricted bool `json:"isKeyRestricted"` + IsFreshUserVerificationRequired bool `json:"isFreshUserVerificationRequired"` + MatcherProtection []string `json:"matcherProtection"` + CryptoStrength uint16 `json:"cryptoStrength"` + AttachmentHint []string `json:"attachmentHint"` + TcDisplay []string `json:"tcDisplay"` + TcDisplayContentType string `json:"tcDisplayContentType"` + TcDisplayPNGCharacteristics []DisplayPNGCharacteristicsDescriptor `json:"tcDisplayPNGCharacteristics"` + AttestationRootCertificates []string `json:"attestationRootCertificates"` + EcdaaTrustAnchors []EcdaaTrustAnchor `json:"ecdaaTrustAnchors"` + Icon string `json:"icon"` + SupportedExtensions []ExtensionDescriptor `json:"supportedExtensions"` + AuthenticatorGetInfo AuthenticatorGetInfoJSON `json:"authenticatorGetInfo"` +} + +func (j StatementJSON) Parse() (statement Statement, err error) { + var aaguid uuid.UUID + + if len(j.AaGUID) != 0 { + if aaguid, err = uuid.Parse(j.AaGUID); err != nil { + return statement, fmt.Errorf("error occurred parsing statement with description '%s': error occurred parsing AAGUID value: %w", j.Description, err) + } + } + + n := len(j.AttestationRootCertificates) + + certificates := make([]*x509.Certificate, n) + + for i := 0; i < n; i++ { + if certificates[i], err = mdsParseX509Certificate(j.AttestationRootCertificates[i]); err != nil { + return statement, fmt.Errorf("error occurred parsing statement with description '%s': error occurred parsing attestation root certificate %d value: %w", j.Description, i, err) + } + } + + var icon *url.URL + + if len(j.Icon) != 0 { + if icon, err = url.ParseRequestURI(j.Icon); err != nil { + return statement, fmt.Errorf("error occurred parsing statement with description '%s': error occurred parsing icon value: %w", j.Description, err) + } + } + + var info AuthenticatorGetInfo + + if info, err = j.AuthenticatorGetInfo.Parse(); err != nil { + return statement, fmt.Errorf("error occurred parsing statement with description '%s': error occurred parsing authenticator get info value: %w", j.Description, err) + } + + return Statement{ + LegalHeader: j.LegalHeader, + Aaid: j.Aaid, + AaGUID: aaguid, + AttestationCertificateKeyIdentifiers: j.AttestationCertificateKeyIdentifiers, + Description: j.Description, + AlternativeDescriptions: j.AlternativeDescriptions, + AuthenticatorVersion: j.AuthenticatorVersion, + ProtocolFamily: j.ProtocolFamily, + Schema: j.Schema, + Upv: j.Upv, + AuthenticationAlgorithms: j.AuthenticationAlgorithms, + PublicKeyAlgAndEncodings: j.PublicKeyAlgAndEncodings, + AttestationTypes: j.AttestationTypes, + UserVerificationDetails: j.UserVerificationDetails, + KeyProtection: j.KeyProtection, + IsKeyRestricted: j.IsKeyRestricted, + IsFreshUserVerificationRequired: j.IsFreshUserVerificationRequired, + MatcherProtection: j.MatcherProtection, + CryptoStrength: j.CryptoStrength, + AttachmentHint: j.AttachmentHint, + TcDisplay: j.TcDisplay, + TcDisplayContentType: j.TcDisplayContentType, + TcDisplayPNGCharacteristics: j.TcDisplayPNGCharacteristics, + AttestationRootCertificates: certificates, + EcdaaTrustAnchors: j.EcdaaTrustAnchors, + Icon: icon, + SupportedExtensions: j.SupportedExtensions, + AuthenticatorGetInfo: info, + }, nil +} + +// BiometricStatusReport is a structure representing the BiometricStatusReport MDS3 dictionary. +// Contains the current status of the authenticator's biometric component. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#biometricstatusreport-dictionary type BiometricStatusReport struct { // Achieved level of the biometric certification of this biometric component of the authenticator - CertLevel uint16 `json:"certLevel"` + CertLevel uint16 + // A single USER_VERIFY constant indicating the modality of the biometric component - Modality string `json:"modality"` + Modality string + // ISO-8601 formatted date since when the certLevel achieved, if applicable. If no date is given, the status is assumed to be effective while present. - EffectiveDate string `json:"effectiveDate"` + EffectiveDate time.Time + // Describes the externally visible aspects of the Biometric Certification evaluation. - CertificationDescriptor string `json:"certificationDescriptor"` + CertificationDescriptor string + // The unique identifier for the issued Biometric Certification. - CertificateNumber string `json:"certificateNumber"` + CertificateNumber string + // The version of the Biometric Certification Policy the implementation is Certified to, e.g. "1.0.0". - CertificationPolicyVersion string `json:"certificationPolicyVersion"` + CertificationPolicyVersion string + // The version of the Biometric Requirements [FIDOBiometricsRequirements] the implementation is certified to, e.g. "1.0.0". + CertificationRequirementsVersion string +} + +// BiometricStatusReportJSON is a structure representing the BiometricStatusReport MDS3 dictionary. +// Contains the current status of the authenticator's biometric component. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#biometricstatusreport-dictionary +type BiometricStatusReportJSON struct { + CertLevel uint16 `json:"certLevel"` + Modality string `json:"modality"` + EffectiveDate string `json:"effectiveDate"` + CertificationDescriptor string `json:"certificationDescriptor"` + CertificateNumber string `json:"certificateNumber"` + + CertificationPolicyVersion string `json:"certificationPolicyVersion"` CertificationRequirementsVersion string `json:"certificationRequirementsVersion"` } -// StatusReport - Contains the current BiometricStatusReport of one of the authenticator's biometric component. -// https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#statusreport-dictionary +func (j BiometricStatusReportJSON) Parse() (report BiometricStatusReport, err error) { + var effective time.Time + + if effective, err = time.Parse(time.DateOnly, j.EffectiveDate); err != nil { + return report, fmt.Errorf("error occurred parsing effective date value: %w", err) + } + + return BiometricStatusReport{ + CertLevel: j.CertLevel, + Modality: j.Modality, + EffectiveDate: effective, + CertificationDescriptor: j.CertificationDescriptor, + CertificateNumber: j.CertificateNumber, + CertificationPolicyVersion: j.CertificationPolicyVersion, + CertificationRequirementsVersion: j.CertificationRequirementsVersion, + }, nil +} + +// StatusReport is a structure representing the StatusReport MDS3 dictionary. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#statusreport-dictionary type StatusReport struct { // Status of the authenticator. Additional fields MAY be set depending on this value. - Status AuthenticatorStatus `json:"status"` + Status AuthenticatorStatus + // ISO-8601 formatted date since when the status code was set, if applicable. If no date is given, the status is assumed to be effective while present. - EffectiveDate string `json:"effectiveDate"` + EffectiveDate time.Time + // The authenticatorVersion that this status report relates to. In the case of FIDO_CERTIFIED* status values, the status applies to higher authenticatorVersions until there is a new statusReport. - AuthenticatorVersion uint32 `json:"authenticatorVersion"` + AuthenticatorVersion uint32 + // Base64-encoded [RFC4648] (not base64url!) DER [ITU-X690-2008] PKIX certificate value related to the current status, if applicable. - Certificate string `json:"certificate"` + Certificate *x509.Certificate + // HTTPS URL where additional information may be found related to the current status, if applicable. - URL string `json:"url"` + URL *url.URL + // Describes the externally visible aspects of the Authenticator Certification evaluation. - CertificationDescriptor string `json:"certificationDescriptor"` + CertificationDescriptor string + // The unique identifier for the issued Certification. - CertificateNumber string `json:"certificateNumber"` + CertificateNumber string + // The version of the Authenticator Certification Policy the implementation is Certified to, e.g. "1.0.0". - CertificationPolicyVersion string `json:"certificationPolicyVersion"` + CertificationPolicyVersion string + // The Document Version of the Authenticator Security Requirements (DV) [FIDOAuthenticatorSecurityRequirements] the implementation is certified to, e.g. "1.2.0". - CertificationRequirementsVersion string `json:"certificationRequirementsVersion"` + CertificationRequirementsVersion string } -// AuthenticatorAttestationType - The ATTESTATION constants are 16 bit long integers indicating the specific attestation that authenticator supports. -// Each constant has a case-sensitive string representation (in quotes), which is used in the authoritative metadata for FIDO authenticators. -type AuthenticatorAttestationType string - -const ( - // BasicFull - Indicates full basic attestation, based on an attestation private key shared among a class of authenticators (e.g. same model). Authenticators must provide its attestation signature during the registration process for the same reason. The attestation trust anchor is shared with FIDO Servers out of band (as part of the Metadata). This sharing process should be done according to [UAFMetadataService]. - BasicFull AuthenticatorAttestationType = "basic_full" - // BasicSurrogate - Just syntactically a Basic Attestation. The attestation object self-signed, i.e. it is signed using the UAuth.priv key, i.e. the key corresponding to the UAuth.pub key included in the attestation object. As a consequence it does not provide a cryptographic proof of the security characteristics. But it is the best thing we can do if the authenticator is not able to have an attestation private key. - BasicSurrogate AuthenticatorAttestationType = "basic_surrogate" - // Ecdaa - Indicates use of elliptic curve based direct anonymous attestation as defined in [FIDOEcdaaAlgorithm]. Support for this attestation type is optional at this time. It might be required by FIDO Certification. - Ecdaa AuthenticatorAttestationType = "ecdaa" - // AttCA - Indicates PrivacyCA attestation as defined in [TCG-CMCProfile-AIKCertEnroll]. Support for this attestation type is optional at this time. It might be required by FIDO Certification. - AttCA AuthenticatorAttestationType = "attca" - // AnonCA In this case, the authenticator uses an Anonymization CA which dynamically generates per-credential attestation certificates such that the attestation statements presented to Relying Parties do not provide uniquely identifiable information, e.g., that might be used for tracking purposes. The applicable [WebAuthn] attestation formats "fmt" are Google SafetyNet Attestation "android-safetynet", Android Keystore Attestation "android-key", Apple Anonymous Attestation "apple", and Apple Application Attestation "apple-appattest". - AnonCA AuthenticatorAttestationType = "anonca" - // None - Indicates absence of attestation - None AuthenticatorAttestationType = "none" -) +// StatusReportJSON is an intermediary JSON/JWT structure representing the StatusReport MDS3 dictionary. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#statusreport-dictionary +type StatusReportJSON struct { + Status AuthenticatorStatus `json:"status"` + EffectiveDate string `json:"effectiveDate"` + AuthenticatorVersion uint32 `json:"authenticatorVersion"` + Certificate string `json:"certificate"` + URL string `json:"url"` + CertificationDescriptor string `json:"certificationDescriptor"` + CertificateNumber string `json:"certificateNumber"` + CertificationPolicyVersion string `json:"certificationPolicyVersion"` + CertificationRequirementsVersion string `json:"certificationRequirementsVersion"` +} -// AuthenticatorStatus - This enumeration describes the status of an authenticator model as identified by its AAID and potentially some additional information (such as a specific attestation key). -// https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#authenticatorstatus-enum -type AuthenticatorStatus string - -const ( - // NotFidoCertified - This authenticator is not FIDO certified. - NotFidoCertified AuthenticatorStatus = "NOT_FIDO_CERTIFIED" - // FidoCertified - This authenticator has passed FIDO functional certification. This certification scheme is phased out and will be replaced by FIDO_CERTIFIED_L1. - FidoCertified AuthenticatorStatus = "FIDO_CERTIFIED" - // UserVerificationBypass - Indicates that malware is able to bypass the user verification. This means that the authenticator could be used without the user's consent and potentially even without the user's knowledge. - UserVerificationBypass AuthenticatorStatus = "USER_VERIFICATION_BYPASS" - // AttestationKeyCompromise - Indicates that an attestation key for this authenticator is known to be compromised. Additional data should be supplied, including the key identifier and the date of compromise, if known. - AttestationKeyCompromise AuthenticatorStatus = "ATTESTATION_KEY_COMPROMISE" - // UserKeyRemoteCompromise - This authenticator has identified weaknesses that allow registered keys to be compromised and should not be trusted. This would include both, e.g. weak entropy that causes predictable keys to be generated or side channels that allow keys or signatures to be forged, guessed or extracted. - UserKeyRemoteCompromise AuthenticatorStatus = "USER_KEY_REMOTE_COMPROMISE" - // UserKeyPhysicalCompromise - This authenticator has known weaknesses in its key protection mechanism(s) that allow user keys to be extracted by an adversary in physical possession of the device. - UserKeyPhysicalCompromise AuthenticatorStatus = "USER_KEY_PHYSICAL_COMPROMISE" - // UpdateAvailable - A software or firmware update is available for the device. Additional data should be supplied including a URL where users can obtain an update and the date the update was published. - UpdateAvailable AuthenticatorStatus = "UPDATE_AVAILABLE" - // Revoked - The FIDO Alliance has determined that this authenticator should not be trusted for any reason, for example if it is known to be a fraudulent product or contain a deliberate backdoor. - Revoked AuthenticatorStatus = "REVOKED" - // SelfAssertionSubmitted - The authenticator vendor has completed and submitted the self-certification checklist to the FIDO Alliance. If this completed checklist is publicly available, the URL will be specified in StatusReport.url. - SelfAssertionSubmitted AuthenticatorStatus = "SELF_ASSERTION_SUBMITTED" - // FidoCertifiedL1 - The authenticator has passed FIDO Authenticator certification at level 1. This level is the more strict successor of FIDO_CERTIFIED. - FidoCertifiedL1 AuthenticatorStatus = "FIDO_CERTIFIED_L1" - // FidoCertifiedL1plus - The authenticator has passed FIDO Authenticator certification at level 1+. This level is the more than level 1. - FidoCertifiedL1plus AuthenticatorStatus = "FIDO_CERTIFIED_L1plus" - // FidoCertifiedL2 - The authenticator has passed FIDO Authenticator certification at level 2. This level is more strict than level 1+. - FidoCertifiedL2 AuthenticatorStatus = "FIDO_CERTIFIED_L2" - // FidoCertifiedL2plus - The authenticator has passed FIDO Authenticator certification at level 2+. This level is more strict than level 2. - FidoCertifiedL2plus AuthenticatorStatus = "FIDO_CERTIFIED_L2plus" - // FidoCertifiedL3 - The authenticator has passed FIDO Authenticator certification at level 3. This level is more strict than level 2+. - FidoCertifiedL3 AuthenticatorStatus = "FIDO_CERTIFIED_L3" - // FidoCertifiedL3plus - The authenticator has passed FIDO Authenticator certification at level 3+. This level is more strict than level 3. - FidoCertifiedL3plus AuthenticatorStatus = "FIDO_CERTIFIED_L3plus" -) +func (j StatusReportJSON) Parse() (report StatusReport, err error) { + var certificate *x509.Certificate -// UndesiredAuthenticatorStatus is an array of undesirable authenticator statuses -var UndesiredAuthenticatorStatus = [...]AuthenticatorStatus{ - AttestationKeyCompromise, - UserVerificationBypass, - UserKeyRemoteCompromise, - UserKeyPhysicalCompromise, - Revoked, -} + if len(j.Certificate) != 0 { + if certificate, err = mdsParseX509Certificate(j.Certificate); err != nil { + return report, fmt.Errorf("error occurred parsing certificate value: %w", err) + } + } + + var effective time.Time + + if effective, err = time.Parse(time.DateOnly, j.EffectiveDate); err != nil { + return report, fmt.Errorf("error occurred parsing effective date value: %w", err) + } + + var uri *url.URL -// IsUndesiredAuthenticatorStatus returns whether the supplied authenticator status is desirable or not -func IsUndesiredAuthenticatorStatus(status AuthenticatorStatus) bool { - for _, s := range UndesiredAuthenticatorStatus { - if s == status { - return true + if len(j.URL) != 0 { + if uri, err = url.ParseRequestURI(j.URL); err != nil { + if !strings.HasPrefix(j.URL, "http") { + var e error + + if uri, e = url.ParseRequestURI(fmt.Sprintf("https://%s", j.URL)); e != nil { + return report, fmt.Errorf("error occurred parsing URL value: %w", err) + } + } } } - return false + return StatusReport{ + Status: j.Status, + EffectiveDate: effective, + AuthenticatorVersion: j.AuthenticatorVersion, + Certificate: certificate, + URL: uri, + CertificationDescriptor: j.CertificationDescriptor, + CertificateNumber: j.CertificateNumber, + CertificationPolicyVersion: j.CertificationPolicyVersion, + CertificationRequirementsVersion: j.CertificationRequirementsVersion, + }, nil } -// RogueListEntry - Contains a list of individual authenticators known to be rogue +// RogueListEntry is a structure representing the RogueListEntry MDS3 dictionary. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#roguelistentry-dictionary type RogueListEntry struct { // Base64url encoding of the rogue authenticator's secret key Sk string `json:"sk"` + // ISO-8601 formatted date since when this entry is effective. Date string `json:"date"` } -// MetadataBLOBPayload - Represents the MetadataBLOBPayload -type MetadataBLOBPayload struct { - // The legalHeader, if present, contains a legal guide for accessing and using metadata, which itself MAY contain URL(s) pointing to further information, such as a full Terms and Conditions statement. - LegalHeader string `json:"legalHeader"` - // The serial number of this UAF Metadata TOC Payload. Serial numbers MUST be consecutive and strictly monotonic, i.e. the successor TOC will have a no value exactly incremented by one. - Number int `json:"no"` - // ISO-8601 formatted date when the next update will be provided at latest. - NextUpdate string `json:"nextUpdate"` - // List of zero or more MetadataTOCPayloadEntry objects. - Entries []MetadataBLOBPayloadEntry `json:"entries"` -} - -// CodeAccuracyDescriptor describes the relevant accuracy/complexity aspects of passcode user verification methods. +// CodeAccuracyDescriptor is a structure representing the CodeAccuracyDescriptor MDS3 dictionary. +// It describes the relevant accuracy/complexity aspects of passcode user verification methods. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#codeaccuracydescriptor-dictionary type CodeAccuracyDescriptor struct { // The numeric system base (radix) of the code, e.g. 10 in the case of decimal digits. Base uint16 `json:"base"` + // The minimum number of digits of the given base required for that code, e.g. 4 in the case of 4 digits. MinLength uint16 `json:"minLength"` + // Maximum number of false attempts before the authenticator will block this method (at least for some time). 0 means it will never block. MaxRetries uint16 `json:"maxRetries"` + // Enforced minimum number of seconds wait time after blocking (e.g. due to forced reboot or similar). // 0 means this user verification method will be blocked, either permanently or until an alternative user verification method method succeeded. // All alternative user verification methods MUST be specified appropriately in the Metadata in userVerificationDetails. BlockSlowdown uint16 `json:"blockSlowdown"` } -// The BiometricAccuracyDescriptor describes relevant accuracy/complexity aspects in the case of a biometric user verification method. +// BiometricAccuracyDescriptor is a structure representing the BiometricAccuracyDescriptor MDS3 dictionary. +// It describes relevant accuracy/complexity aspects in the case of a biometric user verification method. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#biometricaccuracydescriptor-dictionary type BiometricAccuracyDescriptor struct { // The false rejection rate [ISO19795-1] for a single template, i.e. the percentage of verification transactions with truthful claims of identity that are incorrectly denied. - SelfAttestedFRR int64 `json:"selfAttestedFRR "` + SelfAttestedFRR int64 `json:"selfAttestedFRR"` + // The false acceptance rate [ISO19795-1] for a single template, i.e. the percentage of verification transactions with wrongful claims of identity that are incorrectly confirmed. - SelfAttestedFAR int64 `json:"selfAttestedFAR "` + SelfAttestedFAR int64 `json:"selfAttestedFAR"` + // Maximum number of alternative templates from different fingers allowed. MaxTemplates uint16 `json:"maxTemplates"` + // Maximum number of false attempts before the authenticator will block this method (at least for some time). 0 means it will never block. MaxRetries uint16 `json:"maxRetries"` + // Enforced minimum number of seconds wait time after blocking (e.g. due to forced reboot or similar). // 0 means that this user verification method will be blocked either permanently or until an alternative user verification method succeeded. // All alternative user verification methods MUST be specified appropriately in the metadata in userVerificationDetails. BlockSlowdown uint16 `json:"blockSlowdown"` } -// The PatternAccuracyDescriptor describes relevant accuracy/complexity aspects in the case that a pattern is used as the user verification method. +// PatternAccuracyDescriptor is a structure representing the PatternAccuracyDescriptor MDS3 dictionary. +// It describes relevant accuracy/complexity aspects in the case that a pattern is used as the user verification method. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#patternaccuracydescriptor-dictionary type PatternAccuracyDescriptor struct { // Number of possible patterns (having the minimum length) out of which exactly one would be the right one, i.e. 1/probability in the case of equal distribution. MinComplexity uint32 `json:"minComplexity"` + // Maximum number of false attempts before the authenticator will block authentication using this method (at least temporarily). 0 means it will never block. MaxRetries uint16 `json:"maxRetries"` + // Enforced minimum number of seconds wait time after blocking (due to forced reboot or similar mechanism). // 0 means this user verification method will be blocked, either permanently or until an alternative user verification method method succeeded. // All alternative user verification methods MUST be specified appropriately in the metadata under userVerificationDetails. BlockSlowdown uint16 `json:"blockSlowdown"` } -// VerificationMethodDescriptor - A descriptor for a specific base user verification method as implemented by the authenticator. +// VerificationMethodDescriptor is a structure representing the VerificationMethodDescriptor MDS3 dictionary. +// It describes a descriptor for a specific base user verification method as implemented by the authenticator. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#verificationmethoddescriptor-dictionary type VerificationMethodDescriptor struct { // a single USER_VERIFY constant (see [FIDORegistry]), not a bit flag combination. This value MUST be non-zero. - UserVerificationMethod string `json:"userVerification"` + UserVerificationMethod string `json:"userVerificationMethod"` + // May optionally be used in the case of method USER_VERIFY_PASSCODE. CaDesc CodeAccuracyDescriptor `json:"caDesc"` + // May optionally be used in the case of method USER_VERIFY_FINGERPRINT, USER_VERIFY_VOICEPRINT, USER_VERIFY_FACEPRINT, USER_VERIFY_EYEPRINT, or USER_VERIFY_HANDPRINT. BaDesc BiometricAccuracyDescriptor `json:"baDesc"` + // May optionally be used in case of method USER_VERIFY_PATTERN. PaDesc PatternAccuracyDescriptor `json:"paDesc"` } -// The rgbPaletteEntry is an RGB three-sample tuple palette entry -type rgbPaletteEntry struct { +// RGBPaletteEntry is a structure representing the RGBPaletteEntry MDS3 dictionary. +// It describes an RGB three-sample tuple palette entry. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#rgbpaletteentry-dictionary +type RGBPaletteEntry struct { // Red channel sample value R uint16 `json:"r"` + // Green channel sample value G uint16 `json:"g"` + // Blue channel sample value B uint16 `json:"b"` } -// The DisplayPNGCharacteristicsDescriptor describes a PNG image characteristics as defined in the PNG [PNG] spec for IHDR (image header) and PLTE (palette table) +// DisplayPNGCharacteristicsDescriptor is a structure representing the DisplayPNGCharacteristicsDescriptor MDS3 dictionary. +// It describes a PNG image characteristics as defined in the PNG [PNG] spec for IHDR (image header) and PLTE (palette table)/ +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#displaypngcharacteristicsdescriptor-dictionary type DisplayPNGCharacteristicsDescriptor struct { // image width Width uint32 `json:"width"` + // image height Height uint32 `json:"height"` + // Bit depth - bits per sample or per palette index. BitDepth byte `json:"bitDepth"` + // Color type defines the PNG image type. ColorType byte `json:"colorType"` + // Compression method used to compress the image data. Compression byte `json:"compression"` + // Filter method is the preprocessing method applied to the image data before compression. Filter byte `json:"filter"` + // Interlace method is the transmission order of the image data. Interlace byte `json:"interlace"` + // 1 to 256 palette entries - Plte []rgbPaletteEntry `json:"plte"` + Plte []RGBPaletteEntry `json:"plte"` } -// EcdaaTrustAnchor - In the case of ECDAA attestation, the ECDAA-Issuer's trust anchor MUST be specified in this field. +// EcdaaTrustAnchor is a structure representing the EcdaaTrustAnchor MDS3 dictionary. +// In the case of ECDAA attestation, the ECDAA-Issuer's trust anchor MUST be specified in this field. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#ecdaatrustanchor-dictionary type EcdaaTrustAnchor struct { // base64url encoding of the result of ECPoint2ToB of the ECPoint2 X X string `json:"X"` + // base64url encoding of the result of ECPoint2ToB of the ECPoint2 Y Y string `json:"Y"` + // base64url encoding of the result of BigNumberToB(c) C string `json:"c"` + // base64url encoding of the result of BigNumberToB(sx) SX string `json:"sx"` + // base64url encoding of the result of BigNumberToB(sy) SY string `json:"sy"` + // Name of the Barreto-Naehrig elliptic curve for G1. "BN_P256", "BN_P638", "BN_ISOP256", and "BN_ISOP512" are supported. G1Curve string `json:"G1Curve"` } -// ExtensionDescriptor - This descriptor contains an extension supported by the authenticator. +// ExtensionDescriptor is a structure representing the ExtensionDescriptor MDS3 dictionary. +// This descriptor contains an extension supported by the authenticator. +// +// See: https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#extensiondescriptor-dictionary type ExtensionDescriptor struct { // Identifies the extension. ID string `json:"id"` + // The TAG of the extension if this was assigned. TAGs are assigned to extensions if they could appear in an assertion. Tag uint16 `json:"tag"` + // Contains arbitrary data further describing the extension and/or data needed to correctly process the extension. Data string `json:"data"` + // Indicates whether unknown extensions must be ignored (false) or must lead to an error (true) when the extension is to be processed by the FIDO Server, FIDO Client, ASM, or FIDO Authenticator. FailIfUnknown bool `json:"fail_if_unknown"` } -// MetadataStatement - Authenticator metadata statements are used directly by the FIDO server at a relying party, but the information contained in the authoritative statement is used in several other places. -type MetadataStatement struct { - // The legalHeader, if present, contains a legal guide for accessing and using metadata, which itself MAY contain URL(s) pointing to further information, such as a full Terms and Conditions statement. - LegalHeader string `json:"legalHeader"` - // The Authenticator Attestation ID. - Aaid string `json:"aaid"` - // The Authenticator Attestation GUID. - AaGUID string `json:"aaguid"` - // A list of the attestation certificate public key identifiers encoded as hex string. - AttestationCertificateKeyIdentifiers []string `json:"attestationCertificateKeyIdentifiers"` - // A human-readable, short description of the authenticator, in English. - Description string `json:"description"` - // A list of human-readable short descriptions of the authenticator in different languages. - AlternativeDescriptions map[string]string `json:"alternativeDescriptions"` - // Earliest (i.e. lowest) trustworthy authenticatorVersion meeting the requirements specified in this metadata statement. - AuthenticatorVersion uint32 `json:"authenticatorVersion"` - // The FIDO protocol family. The values "uaf", "u2f", and "fido2" are supported. - ProtocolFamily string `json:"protocolFamily"` - // The FIDO unified protocol version(s) (related to the specific protocol family) supported by this authenticator. - Upv []Version `json:"upv"` - // The list of authentication algorithms supported by the authenticator. - AuthenticationAlgorithms []AuthenticationAlgorithm `json:"authenticationAlgorithms"` - // The list of public key formats supported by the authenticator during registration operations. - PublicKeyAlgAndEncodings []PublicKeyAlgAndEncoding `json:"publicKeyAlgAndEncodings"` - // The supported attestation type(s). - AttestationTypes []AuthenticatorAttestationType `json:"attestationTypes"` - // A list of alternative VerificationMethodANDCombinations. - UserVerificationDetails [][]VerificationMethodDescriptor `json:"userVerificationDetails"` - // A 16-bit number representing the bit fields defined by the KEY_PROTECTION constants in the FIDO Registry of Predefined Values - KeyProtection []string `json:"keyProtection"` - // This entry is set to true or it is omitted, if the Uauth private key is restricted by the authenticator to only sign valid FIDO signature assertions. - // This entry is set to false, if the authenticator doesn't restrict the Uauth key to only sign valid FIDO signature assertions. - IsKeyRestricted bool `json:"isKeyRestricted"` - // This entry is set to true or it is omitted, if Uauth key usage always requires a fresh user verification - // This entry is set to false, if the Uauth key can be used without requiring a fresh user verification, e.g. without any additional user interaction, if the user was verified a (potentially configurable) caching time ago. - IsFreshUserVerificationRequired bool `json:"isFreshUserVerificationRequired"` - // A 16-bit number representing the bit fields defined by the MATCHER_PROTECTION constants in the FIDO Registry of Predefined Values - MatcherProtection []string `json:"matcherProtection"` - // The authenticator's overall claimed cryptographic strength in bits (sometimes also called security strength or security level). - CryptoStrength uint16 `json:"cryptoStrength"` - // A 32-bit number representing the bit fields defined by the ATTACHMENT_HINT constants in the FIDO Registry of Predefined Values - AttachmentHint []string `json:"attachmentHint"` - // A 16-bit number representing a combination of the bit flags defined by the TRANSACTION_CONFIRMATION_DISPLAY constants in the FIDO Registry of Predefined Values - TcDisplay []string `json:"tcDisplay"` - // Supported MIME content type [RFC2049] for the transaction confirmation display, such as text/plain or image/png. - TcDisplayContentType string `json:"tcDisplayContentType"` - // A list of alternative DisplayPNGCharacteristicsDescriptor. Each of these entries is one alternative of supported image characteristics for displaying a PNG image. - TcDisplayPNGCharacteristics []DisplayPNGCharacteristicsDescriptor `json:"tcDisplayPNGCharacteristics"` - // Each element of this array represents a PKIX [RFC5280] X.509 certificate that is a valid trust anchor for this authenticator model. - // Multiple certificates might be used for different batches of the same model. - // The array does not represent a certificate chain, but only the trust anchor of that chain. - // A trust anchor can be a root certificate, an intermediate CA certificate or even the attestation certificate itself. - AttestationRootCertificates []string `json:"attestationRootCertificates"` - // A list of trust anchors used for ECDAA attestation. This entry MUST be present if and only if attestationType includes ATTESTATION_ECDAA. - EcdaaTrustAnchors []EcdaaTrustAnchor `json:"ecdaaTrustAnchors"` - // A data: url [RFC2397] encoded PNG [PNG] icon for the Authenticator. - Icon string `json:"icon"` - // List of extensions supported by the authenticator. - SupportedExtensions []ExtensionDescriptor `json:"supportedExtensions"` - // Describes supported versions, extensions, AAGUID of the device and its capabilities - AuthenticatorGetInfo AuthenticatorGetInfo `json:"authenticatorGetInfo"` -} - -type AuthenticationAlgorithm string - -const ( - // An ECDSA signature on the NIST secp256r1 curve which must have raw R and S buffers, encoded in big-endian order. - ALG_SIGN_SECP256R1_ECDSA_SHA256_RAW AuthenticationAlgorithm = "secp256r1_ecdsa_sha256_raw" - // DER ITU-X690-2008 encoded ECDSA signature RFC5480 on the NIST secp256r1 curve. - ALG_SIGN_SECP256R1_ECDSA_SHA256_DER AuthenticationAlgorithm = "secp256r1_ecdsa_sha256_der" - // RSASSA-PSS RFC3447 signature must have raw S buffers, encoded in big-endian order RFC4055 RFC4056. - ALG_SIGN_RSASSA_PSS_SHA256_RAW AuthenticationAlgorithm = "rsassa_pss_sha256_raw" - // DER ITU-X690-2008 encoded OCTET STRING (not BIT STRING!) containing the RSASSA-PSS RFC3447 signature RFC4055 RFC4056. - ALG_SIGN_RSASSA_PSS_SHA256_DER AuthenticationAlgorithm = "rsassa_pss_sha256_der" - // An ECDSA signature on the secp256k1 curve which must have raw R and S buffers, encoded in big-endian order. - ALG_SIGN_SECP256K1_ECDSA_SHA256_RAW AuthenticationAlgorithm = "secp256k1_ecdsa_sha256_raw" - // DER ITU-X690-2008 encoded ECDSA signature RFC5480 on the secp256k1 curve. - ALG_SIGN_SECP256K1_ECDSA_SHA256_DER AuthenticationAlgorithm = "secp256k1_ecdsa_sha256_der" - // Chinese SM2 elliptic curve based signature algorithm combined with SM3 hash algorithm OSCCA-SM2 OSCCA-SM3. - ALG_SIGN_SM2_SM3_RAW AuthenticationAlgorithm = "sm2_sm3_raw" - // This is the EMSA-PKCS1-v1_5 signature as defined in RFC3447. - ALG_SIGN_RSA_EMSA_PKCS1_SHA256_RAW AuthenticationAlgorithm = "rsa_emsa_pkcs1_sha256_raw" - // DER ITU-X690-2008 encoded OCTET STRING (not BIT STRING!) containing the EMSA-PKCS1-v1_5 signature as defined in RFC3447. - ALG_SIGN_RSA_EMSA_PKCS1_SHA256_DER AuthenticationAlgorithm = "rsa_emsa_pkcs1_sha256_der" - // RSASSA-PSS RFC3447 signature must have raw S buffers, encoded in big-endian order RFC4055 RFC4056. - ALG_SIGN_RSASSA_PSS_SHA384_RAW AuthenticationAlgorithm = "rsassa_pss_sha384_raw" - // RSASSA-PSS RFC3447 signature must have raw S buffers, encoded in big-endian order RFC4055 RFC4056. - ALG_SIGN_RSASSA_PSS_SHA512_RAW AuthenticationAlgorithm = "rsassa_pss_sha512_raw" - // RSASSA-PKCS1-v1_5 RFC3447 with SHA256(aka RS256) signature must have raw S buffers, encoded in big-endian order RFC8017 RFC4056 - ALG_SIGN_RSASSA_PKCSV15_SHA256_RAW AuthenticationAlgorithm = "rsassa_pkcsv15_sha256_raw" - // RSASSA-PKCS1-v1_5 RFC3447 with SHA384(aka RS384) signature must have raw S buffers, encoded in big-endian order RFC8017 RFC4056 - ALG_SIGN_RSASSA_PKCSV15_SHA384_RAW AuthenticationAlgorithm = "rsassa_pkcsv15_sha384_raw" - // RSASSA-PKCS1-v1_5 RFC3447 with SHA512(aka RS512) signature must have raw S buffers, encoded in big-endian order RFC8017 RFC4056 - ALG_SIGN_RSASSA_PKCSV15_SHA512_RAW AuthenticationAlgorithm = "rsassa_pkcsv15_sha512_raw" - // RSASSA-PKCS1-v1_5 RFC3447 with SHA1(aka RS1) signature must have raw S buffers, encoded in big-endian order RFC8017 RFC4056 - ALG_SIGN_RSASSA_PKCSV15_SHA1_RAW AuthenticationAlgorithm = "rsassa_pkcsv15_sha1_raw" - // An ECDSA signature on the NIST secp384r1 curve with SHA384(aka: ES384) which must have raw R and S buffers, encoded in big-endian order. - ALG_SIGN_SECP384R1_ECDSA_SHA384_RAW AuthenticationAlgorithm = "secp384r1_ecdsa_sha384_raw" - // An ECDSA signature on the NIST secp512r1 curve with SHA512(aka: ES512) which must have raw R and S buffers, encoded in big-endian order. - ALG_SIGN_SECP521R1_ECDSA_SHA512_RAW AuthenticationAlgorithm = "secp521r1_ecdsa_sha512_raw" - // An EdDSA signature on the curve 25519, which must have raw R and S buffers, encoded in big-endian order. - ALG_SIGN_ED25519_EDDSA_SHA512_RAW AuthenticationAlgorithm = "ed25519_eddsa_sha512_raw" - // An EdDSA signature on the curve Ed448, which must have raw R and S buffers, encoded in big-endian order. - ALG_SIGN_ED448_EDDSA_SHA512_RAW AuthenticationAlgorithm = "ed448_eddsa_sha512_raw" -) - -// TODO: this goes away after webauthncose.CredentialPublicKey gets implemented -type algKeyCose struct { - KeyType webauthncose.COSEKeyType - Algorithm webauthncose.COSEAlgorithmIdentifier - Curve webauthncose.COSEEllipticCurve -} - -func algKeyCoseDictionary() func(AuthenticationAlgorithm) algKeyCose { - mapping := map[AuthenticationAlgorithm]algKeyCose{ - ALG_SIGN_SECP256R1_ECDSA_SHA256_RAW: {KeyType: webauthncose.EllipticKey, Algorithm: webauthncose.AlgES256, Curve: webauthncose.P256}, - ALG_SIGN_SECP256R1_ECDSA_SHA256_DER: {KeyType: webauthncose.EllipticKey, Algorithm: webauthncose.AlgES256, Curve: webauthncose.P256}, - ALG_SIGN_RSASSA_PSS_SHA256_RAW: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgPS256}, - ALG_SIGN_RSASSA_PSS_SHA256_DER: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgPS256}, - ALG_SIGN_SECP256K1_ECDSA_SHA256_RAW: {KeyType: webauthncose.EllipticKey, Algorithm: webauthncose.AlgES256K, Curve: webauthncose.Secp256k1}, - ALG_SIGN_SECP256K1_ECDSA_SHA256_DER: {KeyType: webauthncose.EllipticKey, Algorithm: webauthncose.AlgES256K, Curve: webauthncose.Secp256k1}, - ALG_SIGN_RSASSA_PSS_SHA384_RAW: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgPS384}, - ALG_SIGN_RSASSA_PSS_SHA512_RAW: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgPS512}, - ALG_SIGN_RSASSA_PKCSV15_SHA256_RAW: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgRS256}, - ALG_SIGN_RSASSA_PKCSV15_SHA384_RAW: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgRS384}, - ALG_SIGN_RSASSA_PKCSV15_SHA512_RAW: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgRS512}, - ALG_SIGN_RSASSA_PKCSV15_SHA1_RAW: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgRS1}, - ALG_SIGN_SECP384R1_ECDSA_SHA384_RAW: {KeyType: webauthncose.EllipticKey, Algorithm: webauthncose.AlgES384, Curve: webauthncose.P384}, - ALG_SIGN_SECP521R1_ECDSA_SHA512_RAW: {KeyType: webauthncose.EllipticKey, Algorithm: webauthncose.AlgES512, Curve: webauthncose.P521}, - ALG_SIGN_ED25519_EDDSA_SHA512_RAW: {KeyType: webauthncose.OctetKey, Algorithm: webauthncose.AlgEdDSA, Curve: webauthncose.Ed25519}, - ALG_SIGN_ED448_EDDSA_SHA512_RAW: {KeyType: webauthncose.OctetKey, Algorithm: webauthncose.AlgEdDSA, Curve: webauthncose.Ed448}, - } - - return func(key AuthenticationAlgorithm) algKeyCose { - return mapping[key] - } -} - -func AlgKeyMatch(key algKeyCose, algs []AuthenticationAlgorithm) bool { - for _, alg := range algs { - if reflect.DeepEqual(algKeyCoseDictionary()(alg), key) { - return true - } - } - - return false -} - -type PublicKeyAlgAndEncoding string - -const ( - // Raw ANSI X9.62 formatted Elliptic Curve public key. - ALG_KEY_ECC_X962_RAW PublicKeyAlgAndEncoding = "ecc_x962_raw" - // DER ITU-X690-2008 encoded ANSI X.9.62 formatted SubjectPublicKeyInfo RFC5480 specifying an elliptic curve public key. - ALG_KEY_ECC_X962_DER PublicKeyAlgAndEncoding = "ecc_x962_der" - // Raw encoded 2048-bit RSA public key RFC3447. - ALG_KEY_RSA_2048_RAW PublicKeyAlgAndEncoding = "rsa_2048_raw" - // ASN.1 DER [ITU-X690-2008] encoded 2048-bit RSA RFC3447 public key RFC4055. - ALG_KEY_RSA_2048_DER PublicKeyAlgAndEncoding = "rsa_2048_der" - // COSE_Key format, as defined in Section 7 of RFC8152. This encoding includes its own field for indicating the public key algorithm. - ALG_KEY_COSE PublicKeyAlgAndEncoding = "cose" -) - -// Version - Represents a generic version with major and minor fields. +// Version represents a generic version with major and minor fields. type Version struct { // Major version. Major uint16 `json:"major"` + // Minor version. Minor uint16 `json:"minor"` } type AuthenticatorGetInfo struct { // List of supported versions. - Versions []string `json:"versions"` + Versions []string + // List of supported extensions. - Extensions []string `json:"extensions"` + Extensions []string + // The claimed AAGUID. - AaGUID string `json:"aaguid"` + AaGUID uuid.UUID + // List of supported options. - Options map[string]bool `json:"options"` + Options map[string]bool + // Maximum message size supported by the authenticator. - MaxMsgSize uint `json:"maxMsgSize"` + MaxMsgSize uint + // List of supported PIN/UV auth protocols in order of decreasing authenticator preference. - PivUvAuthProtocols []uint `json:"pinUvAuthProtocols"` + PivUvAuthProtocols []uint + // Maximum number of credentials supported in credentialID list at a time by the authenticator. - MaxCredentialCountInList uint `json:"maxCredentialCountInList"` + MaxCredentialCountInList uint + // Maximum Credential ID Length supported by the authenticator. - MaxCredentialIdLength uint `json:"maxCredentialLength"` + MaxCredentialIdLength uint + // List of supported transports. - Transports []string `json:"transports"` + Transports []string + // List of supported algorithms for credential generation, as specified in WebAuthn. - Algorithms []PublicKeyCredentialParameters `json:"algorithms"` + Algorithms []PublicKeyCredentialParameters + // The maximum size, in bytes, of the serialized large-blob array that this authenticator can store. - MaxSerializedLargeBlobArray uint `json:"maxSerializedLargeBlobArray"` + MaxSerializedLargeBlobArray uint + // If this member is present and set to true, the PIN must be changed. - ForcePINChange bool `json:"forcePINChange"` + ForcePINChange bool + // This specifies the current minimum PIN length, in Unicode code points, the authenticator enforces for ClientPIN. - MinPINLength uint `json:"minPINLength"` + MinPINLength uint + // Indicates the firmware version of the authenticator model identified by AAGUID. - FirmwareVersion uint `json:"firmwareVersion"` + FirmwareVersion uint + // Maximum credBlob length in bytes supported by the authenticator. - MaxCredBlobLength uint `json:"maxCredBlobLength"` + MaxCredBlobLength uint + // This specifies the max number of RP IDs that authenticator can set via setMinPINLength subcommand. - MaxRPIDsForSetMinPINLength uint `json:"maxRPIDsForSetMinPINLength"` + MaxRPIDsForSetMinPINLength uint + // This specifies the preferred number of invocations of the getPinUvAuthTokenUsingUvWithPermissions subCommand the platform may attempt before falling back to the getPinUvAuthTokenUsingPinWithPermissions subCommand or displaying an error. - PreferredPlatformUvAttempts uint `json:"preferredPlatformUvAttempts"` + PreferredPlatformUvAttempts uint + // This specifies the user verification modality supported by the authenticator via authenticatorClientPIN's getPinUvAuthTokenUsingUvWithPermissions subcommand. - UvModality uint `json:"uvModality"` + UvModality uint + // This specifies a list of authenticator certifications. - Certifications map[string]float64 `json:"certifications"` + Certifications map[string]float64 + // If this member is present it indicates the estimated number of additional discoverable credentials that can be stored. - RemainingDiscoverableCredentials uint `json:"remainingDiscoverableCredentials"` + RemainingDiscoverableCredentials uint + // If present the authenticator supports the authenticatorConfig vendorPrototype subcommand, and its value is a list of authenticatorConfig vendorCommandId values supported, which MAY be empty. - VendorPrototypeConfigCommands []uint `json:"vendorPrototypeConfigCommands"` + VendorPrototypeConfigCommands []uint +} + +type AuthenticatorGetInfoJSON struct { + Versions []string `json:"versions"` + Extensions []string `json:"extensions"` + AaGUID string `json:"aaguid"` + Options map[string]bool `json:"options"` + MaxMsgSize uint `json:"maxMsgSize"` + PivUvAuthProtocols []uint `json:"pinUvAuthProtocols"` + MaxCredentialCountInList uint `json:"maxCredentialCountInList"` + MaxCredentialIdLength uint `json:"maxCredentialIdLength"` + Transports []string `json:"transports"` + Algorithms []PublicKeyCredentialParameters `json:"algorithms"` + MaxSerializedLargeBlobArray uint `json:"maxSerializedLargeBlobArray"` + ForcePINChange bool `json:"forcePINChange"` + MinPINLength uint `json:"minPINLength"` + FirmwareVersion uint `json:"firmwareVersion"` + MaxCredBlobLength uint `json:"maxCredBlobLength"` + MaxRPIDsForSetMinPINLength uint `json:"maxRPIDsForSetMinPINLength"` + PreferredPlatformUvAttempts uint `json:"preferredPlatformUvAttempts"` + UvModality uint `json:"uvModality"` + Certifications map[string]float64 `json:"certifications"` + RemainingDiscoverableCredentials uint `json:"remainingDiscoverableCredentials"` + VendorPrototypeConfigCommands []uint `json:"vendorPrototypeConfigCommands"` +} + +func (j AuthenticatorGetInfoJSON) Parse() (info AuthenticatorGetInfo, err error) { + var aaguid uuid.UUID + + if len(j.AaGUID) != 0 { + if aaguid, err = uuid.Parse(j.AaGUID); err != nil { + return info, fmt.Errorf("error occurred parsing AAGUID value: %w", err) + } + } + + return AuthenticatorGetInfo{ + Versions: j.Versions, + Extensions: j.Extensions, + AaGUID: aaguid, + Options: j.Options, + MaxMsgSize: j.MaxMsgSize, + PivUvAuthProtocols: j.PivUvAuthProtocols, + MaxCredentialCountInList: j.MaxCredentialCountInList, + MaxCredentialIdLength: j.MaxCredentialIdLength, + Transports: j.Transports, + Algorithms: j.Algorithms, + MaxSerializedLargeBlobArray: j.MaxSerializedLargeBlobArray, + ForcePINChange: j.ForcePINChange, + MinPINLength: j.MinPINLength, + FirmwareVersion: j.FirmwareVersion, + MaxCredBlobLength: j.MaxCredBlobLength, + MaxRPIDsForSetMinPINLength: j.MaxRPIDsForSetMinPINLength, + PreferredPlatformUvAttempts: j.PreferredPlatformUvAttempts, + UvModality: j.UvModality, + Certifications: j.Certifications, + RemainingDiscoverableCredentials: j.RemainingDiscoverableCredentials, + VendorPrototypeConfigCommands: j.VendorPrototypeConfigCommands, + }, nil } // MDSGetEndpointsRequest is the request sent to the conformance metadata getEndpoints endpoint. @@ -541,189 +910,21 @@ type MDSGetEndpointsRequest struct { type MDSGetEndpointsResponse struct { // The status of the response. Status string `json:"status"` + // An array of urls, each pointing to a MetadataTOCPayload. Result []string `json:"result"` } -func unmarshalMDSBLOB(body []byte, c http.Client) (MetadataBLOBPayload, error) { - var payload MetadataBLOBPayload - - token, err := jwt.Parse(string(body), func(token *jwt.Token) (interface{}, error) { - // 2. If the x5u attribute is present in the JWT Header, then - if _, ok := token.Header["x5u"].([]interface{}); ok { - // never seen an x5u here, although it is in the spec - return nil, errors.New("x5u encountered in header of metadata TOC payload") - } - var chain []interface{} - // 3. If the x5u attribute is missing, the chain should be retrieved from the x5c attribute. - - if x5c, ok := token.Header["x5c"].([]interface{}); !ok { - // If that attribute is missing as well, Metadata TOC signing trust anchor is considered the TOC signing certificate chain. - chain[0] = MDSRoot - } else { - chain = x5c - } - - // The certificate chain MUST be verified to properly chain to the metadata TOC signing trust anchor. - valid, err := validateChain(chain, c) - if !valid || err != nil { - return nil, err - } - - // Chain validated, extract the TOC signing certificate from the chain. Create a buffer large enough to hold the - // certificate bytes. - o := make([]byte, base64.StdEncoding.DecodedLen(len(chain[0].(string)))) - - // base64 decode the certificate into the buffer. - n, err := base64.StdEncoding.Decode(o, []byte(chain[0].(string))) - if err != nil { - return nil, err - } - - // Parse the certificate from the buffer. - cert, err := x509.ParseCertificate(o[:n]) - if err != nil { - return nil, err - } +// DefaultUndesiredAuthenticatorStatuses returns a copy of the defaultUndesiredAuthenticatorStatus slice. +func DefaultUndesiredAuthenticatorStatuses() []AuthenticatorStatus { + undesired := make([]AuthenticatorStatus, len(defaultUndesiredAuthenticatorStatus)) - // 4. Verify the signature of the Metadata TOC object using the TOC signing certificate chain - // jwt.Parse() uses the TOC signing certificate public key internally to verify the signature. - return cert.PublicKey, err - }) + copy(undesired, defaultUndesiredAuthenticatorStatus[:]) - if err != nil { - return payload, err - } - - err = mapstructure.Decode(token.Claims, &payload) - - return payload, err + return undesired } -func validateChain(chain []interface{}, c http.Client) (bool, error) { - oRoot := make([]byte, base64.StdEncoding.DecodedLen(len(MDSRoot))) - - nRoot, err := base64.StdEncoding.Decode(oRoot, []byte(MDSRoot)) - if err != nil { - return false, err - } - - rootcert, err := x509.ParseCertificate(oRoot[:nRoot]) - if err != nil { - return false, err - } - - roots := x509.NewCertPool() - - roots.AddCert(rootcert) - - o := make([]byte, base64.StdEncoding.DecodedLen(len(chain[1].(string)))) - - n, err := base64.StdEncoding.Decode(o, []byte(chain[1].(string))) - if err != nil { - return false, err - } - - intcert, err := x509.ParseCertificate(o[:n]) - if err != nil { - return false, err - } - - if revoked, ok := revoke.VerifyCertificate(intcert); !ok { - issuer := intcert.IssuingCertificateURL - - if issuer != nil { - return false, errCRLUnavailable - } - } else if revoked { - return false, errIntermediateCertRevoked - } - - ints := x509.NewCertPool() - ints.AddCert(intcert) - - l := make([]byte, base64.StdEncoding.DecodedLen(len(chain[0].(string)))) - - n, err = base64.StdEncoding.Decode(l, []byte(chain[0].(string))) - if err != nil { - return false, err - } - - leafcert, err := x509.ParseCertificate(l[:n]) - if err != nil { - return false, err - } - - if revoked, ok := revoke.VerifyCertificate(leafcert); !ok { - return false, errCRLUnavailable - } else if revoked { - return false, errLeafCertRevoked - } - - opts := x509.VerifyOptions{ - Roots: roots, - Intermediates: ints, - } - - _, err = leafcert.Verify(opts) - - return err == nil, err -} - -type MetadataError struct { - // Short name for the type of error that has occurred. - Type string `json:"type"` - // Additional details about the error. - Details string `json:"error"` - // Information to help debug the error. - DevInfo string `json:"debug"` -} - -var ( - errIntermediateCertRevoked = &MetadataError{ - Type: "intermediate_revoked", - Details: "Intermediate certificate is on issuers revocation list", - } - errLeafCertRevoked = &MetadataError{ - Type: "leaf_revoked", - Details: "Leaf certificate is on issuers revocation list", - } - errCRLUnavailable = &MetadataError{ - Type: "crl_unavailable", - Details: "Certificate revocation list is unavailable", - } -) - -func (err *MetadataError) Error() string { - return err.Details -} - -func PopulateMetadata(url string) error { - c := &http.Client{ - Timeout: time.Second * 30, - } - - res, err := c.Get(url) - if err != nil { - return err - } - - defer res.Body.Close() - - body, err := io.ReadAll(res.Body) - if err != nil { - return err - } - - blob, err := unmarshalMDSBLOB(body, *c) - if err != nil { - return err - } - - for _, entry := range blob.Entries { - aaguid, _ := uuid.Parse(entry.AaGUID) - Metadata[aaguid] = entry - } - - return err +type EntryError struct { + Error error + EntryJSON } diff --git a/vendor/github.com/go-webauthn/webauthn/metadata/passkey_authenticator.go b/vendor/github.com/go-webauthn/webauthn/metadata/passkey_authenticator.go new file mode 100644 index 0000000000000000000000000000000000000000..bd993d0428d67589739cc7222c45b1b0838ffac9 --- /dev/null +++ b/vendor/github.com/go-webauthn/webauthn/metadata/passkey_authenticator.go @@ -0,0 +1,16 @@ +package metadata + +// PasskeyAuthenticator is a type that represents the schema from the Passkey Developer AAGUID listing. +// +// See: https://github.com/passkeydeveloper/passkey-authenticator-aaguids +type PasskeyAuthenticator map[string]PassKeyAuthenticatorAAGUID + +// PassKeyAuthenticatorAAGUID is a type that represents the indivudal schema entry from the Passkey Developer AAGUID +// listing. Used with PasskeyAuthenticator. +// +// See: https://github.com/passkeydeveloper/passkey-authenticator-aaguids +type PassKeyAuthenticatorAAGUID struct { + Name string `json:"name"` + IconDark string `json:"icon_dark,omitempty"` + IconLight string `json:"icon_light,omitempty"` +} diff --git a/vendor/github.com/go-webauthn/webauthn/metadata/status.go b/vendor/github.com/go-webauthn/webauthn/metadata/status.go new file mode 100644 index 0000000000000000000000000000000000000000..f20d716fc4a7a4f4fc254e76f82811e3143e1328 --- /dev/null +++ b/vendor/github.com/go-webauthn/webauthn/metadata/status.go @@ -0,0 +1,62 @@ +package metadata + +import ( + "fmt" + "strings" +) + +// ValidateStatusReports checks a list of StatusReport's against a list of desired and undesired AuthenticatorStatus +// values. If the reports contain all of the desired and none of the undesired status reports then no error is returned +// otherwise an error describing the issue is returned. +func ValidateStatusReports(reports []StatusReport, desired, undesired []AuthenticatorStatus) (err error) { + if len(desired) == 0 && (len(undesired) == 0 || len(reports) == 0) { + return nil + } + + var present, absent []string + + if len(undesired) != 0 { + for _, report := range reports { + for _, status := range undesired { + if report.Status == status { + present = append(present, string(status)) + + continue + } + } + } + } + + if len(desired) != 0 { + desired: + for _, status := range desired { + for _, report := range reports { + if report.Status == status { + continue desired + } + } + + absent = append(absent, string(status)) + } + } + + switch { + case len(present) == 0 && len(absent) == 0: + return nil + case len(present) != 0 && len(absent) == 0: + return &Error{ + Type: "invalid_status", + Details: fmt.Sprintf("The following undesired status reports were present: %s", strings.Join(present, ", ")), + } + case len(present) == 0 && len(absent) != 0: + return &Error{ + Type: "invalid_status", + Details: fmt.Sprintf("The following desired status reports were absent: %s", strings.Join(absent, ", ")), + } + default: + return &Error{ + Type: "invalid_status", + Details: fmt.Sprintf("The following undesired status reports were present: %s; the following desired status reports were absent: %s", strings.Join(present, ", "), strings.Join(absent, ", ")), + } + } +} diff --git a/vendor/github.com/go-webauthn/webauthn/metadata/types.go b/vendor/github.com/go-webauthn/webauthn/metadata/types.go new file mode 100644 index 0000000000000000000000000000000000000000..dcc8913669d28fe5350d354391479fe896d6b0e3 --- /dev/null +++ b/vendor/github.com/go-webauthn/webauthn/metadata/types.go @@ -0,0 +1,329 @@ +package metadata + +import ( + "context" + "errors" + "reflect" + "time" + + "github.com/google/uuid" + + "github.com/go-webauthn/webauthn/protocol/webauthncose" +) + +// The Provider is an interface which describes the elements required to satisfy validation of metadata. +type Provider interface { + // GetEntry returns a MDS3 payload entry given a AAGUID. This + GetEntry(ctx context.Context, aaguid uuid.UUID) (entry *Entry, err error) + + // GetValidateEntry returns true if this provider requires an entry to exist with a AAGUID matching the attestation + // statement during registration. + GetValidateEntry(ctx context.Context) (validate bool) + + // GetValidateEntryPermitZeroAAGUID returns true if attestation statements with zerod AAGUID should be permitted + // when considering the result from GetValidateEntry. i.e. if the AAGUID is zeroed, and GetValidateEntry returns + // true, and this implementation returns true, the attestation statement will pass validation. + GetValidateEntryPermitZeroAAGUID(ctx context.Context) (skip bool) + + // GetValidateTrustAnchor returns true if trust anchor validation of attestation statements is enforced during + // registration. + GetValidateTrustAnchor(ctx context.Context) (validate bool) + + // GetValidateStatus returns true if the status reports for an authenticator should be validated against desired and + // undesired statuses. + GetValidateStatus(ctx context.Context) (validate bool) + + // GetValidateAttestationTypes if true will enforce checking that the provided attestation is possible with the + // given authenticator. + GetValidateAttestationTypes(ctx context.Context) (validate bool) + + // ValidateStatusReports returns nil if the provided authenticator status reports are desired. + ValidateStatusReports(ctx context.Context, reports []StatusReport) (err error) +} + +var ( + ErrNotInitialized = errors.New("metadata: not initialized") +) + +type PublicKeyCredentialParameters struct { + Type string `json:"type"` + Alg webauthncose.COSEAlgorithmIdentifier `json:"alg"` +} + +type AuthenticatorAttestationTypes []AuthenticatorAttestationType + +func (t AuthenticatorAttestationTypes) HasBasicFull() bool { + for _, a := range t { + if a == BasicFull || a == AttCA { + return true + } + } + + return false +} + +// AuthenticatorAttestationType - The ATTESTATION constants are 16 bit long integers indicating the specific attestation that authenticator supports. +// Each constant has a case-sensitive string representation (in quotes), which is used in the authoritative metadata for FIDO authenticators. +type AuthenticatorAttestationType string + +const ( + // BasicFull - Indicates full basic attestation, based on an attestation private key shared among a class of authenticators (e.g. same model). Authenticators must provide its attestation signature during the registration process for the same reason. The attestation trust anchor is shared with FIDO Servers out of band (as part of the Metadata). This sharing process should be done according to [UAFMetadataService]. + BasicFull AuthenticatorAttestationType = "basic_full" + + // BasicSurrogate - Just syntactically a Basic Attestation. The attestation object self-signed, i.e. it is signed using the UAuth.priv key, i.e. the key corresponding to the UAuth.pub key included in the attestation object. As a consequence it does not provide a cryptographic proof of the security characteristics. But it is the best thing we can do if the authenticator is not able to have an attestation private key. + BasicSurrogate AuthenticatorAttestationType = "basic_surrogate" + + // Ecdaa - Indicates use of elliptic curve based direct anonymous attestation as defined in [FIDOEcdaaAlgorithm]. Support for this attestation type is optional at this time. It might be required by FIDO Certification. + Ecdaa AuthenticatorAttestationType = "ecdaa" + + // AttCA - Indicates PrivacyCA attestation as defined in [TCG-CMCProfile-AIKCertEnroll]. Support for this attestation type is optional at this time. It might be required by FIDO Certification. + AttCA AuthenticatorAttestationType = "attca" + + // AnonCA In this case, the authenticator uses an Anonymization CA which dynamically generates per-credential attestation certificates such that the attestation statements presented to Relying Parties do not provide uniquely identifiable information, e.g., that might be used for tracking purposes. The applicable [WebAuthn] attestation formats "fmt" are Google SafetyNet Attestation "android-safetynet", Android Keystore Attestation "android-key", Apple Anonymous Attestation "apple", and Apple Application Attestation "apple-appattest". + AnonCA AuthenticatorAttestationType = "anonca" + + // None - Indicates absence of attestation + None AuthenticatorAttestationType = "none" +) + +// AuthenticatorStatus - This enumeration describes the status of an authenticator model as identified by its AAID and potentially some additional information (such as a specific attestation key). +// https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#authenticatorstatus-enum +type AuthenticatorStatus string + +const ( + // NotFidoCertified - This authenticator is not FIDO certified. + NotFidoCertified AuthenticatorStatus = "NOT_FIDO_CERTIFIED" + // FidoCertified - This authenticator has passed FIDO functional certification. This certification scheme is phased out and will be replaced by FIDO_CERTIFIED_L1. + FidoCertified AuthenticatorStatus = "FIDO_CERTIFIED" + // UserVerificationBypass - Indicates that malware is able to bypass the user verification. This means that the authenticator could be used without the user's consent and potentially even without the user's knowledge. + UserVerificationBypass AuthenticatorStatus = "USER_VERIFICATION_BYPASS" + // AttestationKeyCompromise - Indicates that an attestation key for this authenticator is known to be compromised. Additional data should be supplied, including the key identifier and the date of compromise, if known. + AttestationKeyCompromise AuthenticatorStatus = "ATTESTATION_KEY_COMPROMISE" + // UserKeyRemoteCompromise - This authenticator has identified weaknesses that allow registered keys to be compromised and should not be trusted. This would include both, e.g. weak entropy that causes predictable keys to be generated or side channels that allow keys or signatures to be forged, guessed or extracted. + UserKeyRemoteCompromise AuthenticatorStatus = "USER_KEY_REMOTE_COMPROMISE" + // UserKeyPhysicalCompromise - This authenticator has known weaknesses in its key protection mechanism(s) that allow user keys to be extracted by an adversary in physical possession of the device. + UserKeyPhysicalCompromise AuthenticatorStatus = "USER_KEY_PHYSICAL_COMPROMISE" + // UpdateAvailable - A software or firmware update is available for the device. Additional data should be supplied including a URL where users can obtain an update and the date the update was published. + UpdateAvailable AuthenticatorStatus = "UPDATE_AVAILABLE" + // Revoked - The FIDO Alliance has determined that this authenticator should not be trusted for any reason, for example if it is known to be a fraudulent product or contain a deliberate backdoor. + Revoked AuthenticatorStatus = "REVOKED" + // SelfAssertionSubmitted - The authenticator vendor has completed and submitted the self-certification checklist to the FIDO Alliance. If this completed checklist is publicly available, the URL will be specified in StatusReportJSON.url. + SelfAssertionSubmitted AuthenticatorStatus = "SELF_ASSERTION_SUBMITTED" + // FidoCertifiedL1 - The authenticator has passed FIDO Authenticator certification at level 1. This level is the more strict successor of FIDO_CERTIFIED. + FidoCertifiedL1 AuthenticatorStatus = "FIDO_CERTIFIED_L1" + // FidoCertifiedL1plus - The authenticator has passed FIDO Authenticator certification at level 1+. This level is the more than level 1. + FidoCertifiedL1plus AuthenticatorStatus = "FIDO_CERTIFIED_L1plus" + // FidoCertifiedL2 - The authenticator has passed FIDO Authenticator certification at level 2. This level is more strict than level 1+. + FidoCertifiedL2 AuthenticatorStatus = "FIDO_CERTIFIED_L2" + // FidoCertifiedL2plus - The authenticator has passed FIDO Authenticator certification at level 2+. This level is more strict than level 2. + FidoCertifiedL2plus AuthenticatorStatus = "FIDO_CERTIFIED_L2plus" + // FidoCertifiedL3 - The authenticator has passed FIDO Authenticator certification at level 3. This level is more strict than level 2+. + FidoCertifiedL3 AuthenticatorStatus = "FIDO_CERTIFIED_L3" + // FidoCertifiedL3plus - The authenticator has passed FIDO Authenticator certification at level 3+. This level is more strict than level 3. + FidoCertifiedL3plus AuthenticatorStatus = "FIDO_CERTIFIED_L3plus" +) + +// defaultUndesiredAuthenticatorStatus is an array of undesirable authenticator statuses +var defaultUndesiredAuthenticatorStatus = [...]AuthenticatorStatus{ + AttestationKeyCompromise, + UserVerificationBypass, + UserKeyRemoteCompromise, + UserKeyPhysicalCompromise, + Revoked, +} + +// IsUndesiredAuthenticatorStatus returns whether the supplied authenticator status is desirable or not +func IsUndesiredAuthenticatorStatus(status AuthenticatorStatus) bool { + for _, s := range defaultUndesiredAuthenticatorStatus { + if s == status { + return true + } + } + + return false +} + +// IsUndesiredAuthenticatorStatusSlice returns whether the supplied authenticator status is desirable or not +func IsUndesiredAuthenticatorStatusSlice(status AuthenticatorStatus, values []AuthenticatorStatus) bool { + for _, s := range values { + if s == status { + return true + } + } + + return false +} + +// IsUndesiredAuthenticatorStatusMap returns whether the supplied authenticator status is desirable or not +func IsUndesiredAuthenticatorStatusMap(status AuthenticatorStatus, values map[AuthenticatorStatus]bool) bool { + _, ok := values[status] + + return ok +} + +type AuthenticationAlgorithm string + +const ( + // ALG_SIGN_SECP256R1_ECDSA_SHA256_RAW is an ECDSA signature on the NIST secp256r1 curve which must have raw R and + // S buffers, encoded in big-endian order. + ALG_SIGN_SECP256R1_ECDSA_SHA256_RAW AuthenticationAlgorithm = "secp256r1_ecdsa_sha256_raw" + + // ALG_SIGN_SECP256R1_ECDSA_SHA256_DER is a DER ITU-X690-2008 encoded ECDSA signature RFC5480 on the NIST secp256r1 + // curve. + ALG_SIGN_SECP256R1_ECDSA_SHA256_DER AuthenticationAlgorithm = "secp256r1_ecdsa_sha256_der" + + // ALG_SIGN_RSASSA_PSS_SHA256_RAW is a RSASSA-PSS RFC3447 signature must have raw S buffers, encoded in big-endian + // order RFC4055 RFC4056. + ALG_SIGN_RSASSA_PSS_SHA256_RAW AuthenticationAlgorithm = "rsassa_pss_sha256_raw" + + // ALG_SIGN_RSASSA_PSS_SHA256_DER is a DER ITU-X690-2008 encoded OCTET STRING (not BIT STRING!) containing the + // RSASSA-PSS RFC3447 signature RFC4055 RFC4056. + ALG_SIGN_RSASSA_PSS_SHA256_DER AuthenticationAlgorithm = "rsassa_pss_sha256_der" + + // ALG_SIGN_SECP256K1_ECDSA_SHA256_RAW is an ECDSA signature on the secp256k1 curve which must have raw R and S + // buffers, encoded in big-endian order. + ALG_SIGN_SECP256K1_ECDSA_SHA256_RAW AuthenticationAlgorithm = "secp256k1_ecdsa_sha256_raw" + + // ALG_SIGN_SECP256K1_ECDSA_SHA256_DER is a DER ITU-X690-2008 encoded ECDSA signature RFC5480 on the secp256k1 curve. + ALG_SIGN_SECP256K1_ECDSA_SHA256_DER AuthenticationAlgorithm = "secp256k1_ecdsa_sha256_der" + + // ALG_SIGN_SM2_SM3_RAW is a Chinese SM2 elliptic curve based signature algorithm combined with SM3 hash algorithm + // OSCCA-SM2 OSCCA-SM3. + ALG_SIGN_SM2_SM3_RAW AuthenticationAlgorithm = "sm2_sm3_raw" + + // ALG_SIGN_RSA_EMSA_PKCS1_SHA256_RAW is the EMSA-PKCS1-v1_5 signature as defined in RFC3447. + ALG_SIGN_RSA_EMSA_PKCS1_SHA256_RAW AuthenticationAlgorithm = "rsa_emsa_pkcs1_sha256_raw" + + // ALG_SIGN_RSA_EMSA_PKCS1_SHA256_DER is a DER ITU-X690-2008 encoded OCTET STRING (not BIT STRING!) containing the + // EMSA-PKCS1-v1_5 signature as defined in RFC3447. + ALG_SIGN_RSA_EMSA_PKCS1_SHA256_DER AuthenticationAlgorithm = "rsa_emsa_pkcs1_sha256_der" + + // ALG_SIGN_RSASSA_PSS_SHA384_RAW is a RSASSA-PSS RFC3447 signature must have raw S buffers, encoded in big-endian + // order RFC4055 RFC4056. + ALG_SIGN_RSASSA_PSS_SHA384_RAW AuthenticationAlgorithm = "rsassa_pss_sha384_raw" + + // ALG_SIGN_RSASSA_PSS_SHA512_RAW is a RSASSA-PSS RFC3447 signature must have raw S buffers, encoded in big-endian + // order RFC4055 RFC4056. + ALG_SIGN_RSASSA_PSS_SHA512_RAW AuthenticationAlgorithm = "rsassa_pss_sha512_raw" + + // ALG_SIGN_RSASSA_PKCSV15_SHA256_RAW is a RSASSA-PKCS1-v1_5 RFC3447 with SHA256(aka RS256) signature must have raw + // S buffers, encoded in big-endian order RFC8017 RFC4056 + ALG_SIGN_RSASSA_PKCSV15_SHA256_RAW AuthenticationAlgorithm = "rsassa_pkcsv15_sha256_raw" + + // RSASSA-PKCS1-v1_5 RFC3447 with SHA384(aka RS384) signature must have raw S buffers, encoded in big-endian order RFC8017 RFC4056 + ALG_SIGN_RSASSA_PKCSV15_SHA384_RAW AuthenticationAlgorithm = "rsassa_pkcsv15_sha384_raw" + + // ALG_SIGN_RSASSA_PKCSV15_SHA512_RAW is a RSASSA-PKCS1-v1_5 RFC3447 with SHA512(aka RS512) signature must have raw + // S buffers, encoded in big-endian order RFC8017 RFC4056 + ALG_SIGN_RSASSA_PKCSV15_SHA512_RAW AuthenticationAlgorithm = "rsassa_pkcsv15_sha512_raw" + + // ALG_SIGN_RSASSA_PKCSV15_SHA1_RAW is a RSASSA-PKCS1-v1_5 RFC3447 with SHA1(aka RS1) signature must have raw S + // buffers, encoded in big-endian order RFC8017 RFC4056 + ALG_SIGN_RSASSA_PKCSV15_SHA1_RAW AuthenticationAlgorithm = "rsassa_pkcsv15_sha1_raw" + + // ALG_SIGN_SECP384R1_ECDSA_SHA384_RAW is an ECDSA signature on the NIST secp384r1 curve with SHA384(aka: ES384) + // which must have raw R and S buffers, encoded in big-endian order. + ALG_SIGN_SECP384R1_ECDSA_SHA384_RAW AuthenticationAlgorithm = "secp384r1_ecdsa_sha384_raw" + + // ALG_SIGN_SECP521R1_ECDSA_SHA512_RAW is an ECDSA signature on the NIST secp512r1 curve with SHA512(aka: ES512) + // which must have raw R and S buffers, encoded in big-endian order. + ALG_SIGN_SECP521R1_ECDSA_SHA512_RAW AuthenticationAlgorithm = "secp521r1_ecdsa_sha512_raw" + + // ALG_SIGN_ED25519_EDDSA_SHA512_RAW is an EdDSA signature on the curve 25519, which must have raw R and S buffers, + // encoded in big-endian order. + ALG_SIGN_ED25519_EDDSA_SHA512_RAW AuthenticationAlgorithm = "ed25519_eddsa_sha512_raw" + + // ALG_SIGN_ED448_EDDSA_SHA512_RAW is an EdDSA signature on the curve Ed448, which must have raw R and S buffers, + // encoded in big-endian order. + ALG_SIGN_ED448_EDDSA_SHA512_RAW AuthenticationAlgorithm = "ed448_eddsa_sha512_raw" +) + +// TODO: this goes away after webauthncose.CredentialPublicKey gets implemented +type algKeyCose struct { + KeyType webauthncose.COSEKeyType + Algorithm webauthncose.COSEAlgorithmIdentifier + Curve webauthncose.COSEEllipticCurve +} + +func algKeyCoseDictionary() func(AuthenticationAlgorithm) algKeyCose { + mapping := map[AuthenticationAlgorithm]algKeyCose{ + ALG_SIGN_SECP256R1_ECDSA_SHA256_RAW: {KeyType: webauthncose.EllipticKey, Algorithm: webauthncose.AlgES256, Curve: webauthncose.P256}, + ALG_SIGN_SECP256R1_ECDSA_SHA256_DER: {KeyType: webauthncose.EllipticKey, Algorithm: webauthncose.AlgES256, Curve: webauthncose.P256}, + ALG_SIGN_RSASSA_PSS_SHA256_RAW: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgPS256}, + ALG_SIGN_RSASSA_PSS_SHA256_DER: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgPS256}, + ALG_SIGN_SECP256K1_ECDSA_SHA256_RAW: {KeyType: webauthncose.EllipticKey, Algorithm: webauthncose.AlgES256K, Curve: webauthncose.Secp256k1}, + ALG_SIGN_SECP256K1_ECDSA_SHA256_DER: {KeyType: webauthncose.EllipticKey, Algorithm: webauthncose.AlgES256K, Curve: webauthncose.Secp256k1}, + ALG_SIGN_RSASSA_PSS_SHA384_RAW: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgPS384}, + ALG_SIGN_RSASSA_PSS_SHA512_RAW: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgPS512}, + ALG_SIGN_RSASSA_PKCSV15_SHA256_RAW: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgRS256}, + ALG_SIGN_RSASSA_PKCSV15_SHA384_RAW: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgRS384}, + ALG_SIGN_RSASSA_PKCSV15_SHA512_RAW: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgRS512}, + ALG_SIGN_RSASSA_PKCSV15_SHA1_RAW: {KeyType: webauthncose.RSAKey, Algorithm: webauthncose.AlgRS1}, + ALG_SIGN_SECP384R1_ECDSA_SHA384_RAW: {KeyType: webauthncose.EllipticKey, Algorithm: webauthncose.AlgES384, Curve: webauthncose.P384}, + ALG_SIGN_SECP521R1_ECDSA_SHA512_RAW: {KeyType: webauthncose.EllipticKey, Algorithm: webauthncose.AlgES512, Curve: webauthncose.P521}, + ALG_SIGN_ED25519_EDDSA_SHA512_RAW: {KeyType: webauthncose.OctetKey, Algorithm: webauthncose.AlgEdDSA, Curve: webauthncose.Ed25519}, + ALG_SIGN_ED448_EDDSA_SHA512_RAW: {KeyType: webauthncose.OctetKey, Algorithm: webauthncose.AlgEdDSA, Curve: webauthncose.Ed448}, + } + + return func(key AuthenticationAlgorithm) algKeyCose { + return mapping[key] + } +} + +func AlgKeyMatch(key algKeyCose, algs []AuthenticationAlgorithm) bool { + for _, alg := range algs { + if reflect.DeepEqual(algKeyCoseDictionary()(alg), key) { + return true + } + } + + return false +} + +type PublicKeyAlgAndEncoding string + +const ( + // ALG_KEY_ECC_X962_RAW is a raw ANSI X9.62 formatted Elliptic Curve public key. + ALG_KEY_ECC_X962_RAW PublicKeyAlgAndEncoding = "ecc_x962_raw" + + // ALG_KEY_ECC_X962_DER is a DER ITU-X690-2008 encoded ANSI X.9.62 formatted SubjectPublicKeyInfo RFC5480 specifying an elliptic curve public key. + ALG_KEY_ECC_X962_DER PublicKeyAlgAndEncoding = "ecc_x962_der" + + // ALG_KEY_RSA_2048_RAW is a raw encoded 2048-bit RSA public key RFC3447. + ALG_KEY_RSA_2048_RAW PublicKeyAlgAndEncoding = "rsa_2048_raw" + + // ALG_KEY_RSA_2048_DER is a ASN.1 DER [ITU-X690-2008] encoded 2048-bit RSA RFC3447 public key RFC4055. + ALG_KEY_RSA_2048_DER PublicKeyAlgAndEncoding = "rsa_2048_der" + + // ALG_KEY_COSE is a COSE_Key format, as defined in Section 7 of RFC8152. This encoding includes its own field for indicating the public key algorithm. + ALG_KEY_COSE PublicKeyAlgAndEncoding = "cose" +) + +type Error struct { + // Short name for the type of error that has occurred. + Type string `json:"type"` + + // Additional details about the error. + Details string `json:"error"` + + // Information to help debug the error. + DevInfo string `json:"debug"` +} + +func (e *Error) Error() string { + return e.Details +} + +// Clock is an interface used to implement clock functionality in various metadata areas. +type Clock interface { + // Now returns the current time. + Now() time.Time +} + +// RealClock is just a real clock. +type RealClock struct{} + +// Now returns the current time. +func (RealClock) Now() time.Time { + return time.Now() +} diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/assertion.go b/vendor/github.com/go-webauthn/webauthn/protocol/assertion.go index 897a56cda8cfcbd8fb3ee402b28bfcd0a598ee00..f3caa91815168bbfb1fe9fb581b9bc5eb887fed2 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/assertion.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/assertion.go @@ -15,6 +15,7 @@ import ( // credential for login/assertion. type CredentialAssertionResponse struct { PublicKeyCredential + AssertionResponse AuthenticatorAssertionResponse `json:"response"` } @@ -22,6 +23,7 @@ type CredentialAssertionResponse struct { // that allows us to verify the client and authenticator data inside the response. type ParsedCredentialAssertionData struct { ParsedPublicKeyCredential + Response ParsedAssertionResponse Raw CredentialAssertionResponse } @@ -30,6 +32,7 @@ type ParsedCredentialAssertionData struct { // ParsedAssertionResponse. type AuthenticatorAssertionResponse struct { AuthenticatorResponse + AuthenticatorData URLEncodedBase64 `json:"authenticatorData"` Signature URLEncodedBase64 `json:"signature"` UserHandle URLEncodedBase64 `json:"userHandle,omitempty"` @@ -51,8 +54,10 @@ func ParseCredentialRequestResponse(response *http.Request) (*ParsedCredentialAs return nil, ErrBadRequest.WithDetails("No response given") } - defer response.Body.Close() - defer io.Copy(io.Discard, response.Body) + defer func(request *http.Request) { + _, _ = io.Copy(io.Discard, request.Body) + _ = request.Body.Close() + }(response) return ParseCredentialRequestResponseBody(response.Body) } @@ -64,7 +69,19 @@ func ParseCredentialRequestResponseBody(body io.Reader) (par *ParsedCredentialAs var car CredentialAssertionResponse if err = decodeBody(body, &car); err != nil { - return nil, ErrBadRequest.WithDetails("Parse error for Assertion").WithInfo(err.Error()) + return nil, ErrBadRequest.WithDetails("Parse error for Assertion").WithInfo(err.Error()).WithError(err) + } + + return car.Parse() +} + +// ParseCredentialRequestResponseBytes is an alternative version of ParseCredentialRequestResponseBody that just takes +// a byte slice. +func ParseCredentialRequestResponseBytes(data []byte) (par *ParsedCredentialAssertionData, err error) { + var car CredentialAssertionResponse + + if err = decodeBytes(data, &car); err != nil { + return nil, ErrBadRequest.WithDetails("Parse error for Assertion").WithInfo(err.Error()).WithError(err) } return car.Parse() @@ -80,20 +97,18 @@ func (car CredentialAssertionResponse) Parse() (par *ParsedCredentialAssertionDa } if _, err = base64.RawURLEncoding.DecodeString(car.ID); err != nil { - return nil, ErrBadRequest.WithDetails("CredentialAssertionResponse with ID not base64url encoded") + return nil, ErrBadRequest.WithDetails("CredentialAssertionResponse with ID not base64url encoded").WithError(err) } - if car.Type != "public-key" { + if car.Type != string(PublicKeyCredentialType) { return nil, ErrBadRequest.WithDetails("CredentialAssertionResponse with bad type") } var attachment AuthenticatorAttachment - switch car.AuthenticatorAttachment { - case "platform": - attachment = Platform - case "cross-platform": - attachment = CrossPlatform + switch att := AuthenticatorAttachment(car.AuthenticatorAttachment); att { + case Platform, CrossPlatform: + attachment = att } par = &ParsedCredentialAssertionData{ @@ -114,7 +129,7 @@ func (car CredentialAssertionResponse) Parse() (par *ParsedCredentialAssertionDa } if err = par.Response.AuthenticatorData.Unmarshal(car.AssertionResponse.AuthenticatorData); err != nil { - return nil, ErrParsingData.WithDetails("Error unmarshalling auth data") + return nil, ErrParsingData.WithDetails("Error unmarshalling auth data").WithError(err) } return par, nil @@ -124,14 +139,14 @@ func (car CredentialAssertionResponse) Parse() (par *ParsedCredentialAssertionDa // documentation. // // Specification: §7.2 Verifying an Authentication Assertion (https://www.w3.org/TR/webauthn/#sctn-verifying-assertion) -func (p *ParsedCredentialAssertionData) Verify(storedChallenge string, relyingPartyID string, relyingPartyOrigins []string, appID string, verifyUser bool, credentialBytes []byte) error { +func (p *ParsedCredentialAssertionData) Verify(storedChallenge string, relyingPartyID string, rpOrigins, rpTopOrigins []string, rpTopOriginsVerify TopOriginVerificationMode, appID string, verifyUser bool, credentialBytes []byte) error { // Steps 4 through 6 in verifying the assertion data (https://www.w3.org/TR/webauthn/#verifying-assertion) are - // "assertive" steps, i.e "Let JSONtext be the result of running UTF-8 decode on the value of cData." + // "assertive" steps, i.e. "Let JSONtext be the result of running UTF-8 decode on the value of cData." // We handle these steps in part as we verify but also beforehand - + // // Handle steps 7 through 10 of assertion by verifying stored data against the Collected Client Data - // returned by the authenticator - validError := p.Response.CollectedClientData.Verify(storedChallenge, AssertCeremony, relyingPartyOrigins) + // returned by the authenticator. + validError := p.Response.CollectedClientData.Verify(storedChallenge, AssertCeremony, rpOrigins, rpTopOrigins, rpTopOriginsVerify) if validError != nil { return validError } @@ -161,7 +176,7 @@ func (p *ParsedCredentialAssertionData) Verify(storedChallenge string, relyingPa sigData := append(p.Raw.AssertionResponse.AuthenticatorData, clientDataHash[:]...) var ( - key interface{} + key any err error ) @@ -174,12 +189,12 @@ func (p *ParsedCredentialAssertionData) Verify(storedChallenge string, relyingPa } if err != nil { - return ErrAssertionSignature.WithDetails(fmt.Sprintf("Error parsing the assertion public key: %+v", err)) + return ErrAssertionSignature.WithDetails(fmt.Sprintf("Error parsing the assertion public key: %+v", err)).WithError(err) } valid, err := webauthncose.VerifySignature(key, sigData, p.Response.Signature) if !valid || err != nil { - return ErrAssertionSignature.WithDetails(fmt.Sprintf("Error validating the assertion signature: %+v", err)) + return ErrAssertionSignature.WithDetails(fmt.Sprintf("Error validating the assertion signature: %+v", err)).WithError(err) } return nil diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/attestation.go b/vendor/github.com/go-webauthn/webauthn/protocol/attestation.go index 54716de98914e8862e05346b9db768d3c4d2eeef..55c76c603d5c328acd9918fcd9cd6494035a24bc 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/attestation.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/attestation.go @@ -1,8 +1,8 @@ package protocol import ( + "context" "crypto/sha256" - "crypto/x509" "encoding/json" "fmt" @@ -22,6 +22,14 @@ type AuthenticatorAttestationResponse struct { // The byte slice of clientDataJSON, which becomes CollectedClientData AuthenticatorResponse + Transports []string `json:"transports,omitempty"` + + AuthenticatorData URLEncodedBase64 `json:"authenticatorData"` + + PublicKey URLEncodedBase64 `json:"publicKey"` + + PublicKeyAlgorithm int64 `json:"publicKeyAlgorithm"` + // AttestationObject is the byte slice version of attestationObject. // This attribute contains an attestation object, which is opaque to, and // cryptographically protected against tampering by, the client. The @@ -33,8 +41,6 @@ type AuthenticatorAttestationResponse struct { // requires to validate the attestation statement, as well as to decode and // validate the authenticator data along with the JSON-serialized client data. AttestationObject URLEncodedBase64 `json:"attestationObject"` - - Transports []string `json:"transports,omitempty"` } // ParsedAttestationResponse is the parsed version of AuthenticatorAttestationResponse. @@ -60,21 +66,24 @@ type ParsedAttestationResponse struct { type AttestationObject struct { // The authenticator data, including the newly created public key. See AuthenticatorData for more info AuthData AuthenticatorData + // The byteform version of the authenticator data, used in part for signature validation RawAuthData []byte `json:"authData"` + // The format of the Attestation data. Format string `json:"fmt"` + // The attestation statement data sent back if attestation is requested. - AttStatement map[string]interface{} `json:"attStmt,omitempty"` + AttStatement map[string]any `json:"attStmt,omitempty"` } -type attestationFormatValidationHandler func(AttestationObject, []byte) (string, []interface{}, error) +type attestationFormatValidationHandler func(AttestationObject, []byte, metadata.Provider) (string, []any, error) -var attestationRegistry = make(map[string]attestationFormatValidationHandler) +var attestationRegistry = make(map[AttestationFormat]attestationFormatValidationHandler) // RegisterAttestationFormat is a method to register attestation formats with the library. Generally using one of the // locally registered attestation formats is sufficient. -func RegisterAttestationFormat(format string, handler attestationFormatValidationHandler) { +func RegisterAttestationFormat(format AttestationFormat, handler attestationFormatValidationHandler) { attestationRegistry[format] = handler } @@ -85,18 +94,18 @@ func (ccr *AuthenticatorAttestationResponse) Parse() (p *ParsedAttestationRespon p = &ParsedAttestationResponse{} if err = json.Unmarshal(ccr.ClientDataJSON, &p.CollectedClientData); err != nil { - return nil, ErrParsingData.WithInfo(err.Error()) + return nil, ErrParsingData.WithInfo(err.Error()).WithError(err) } if err = webauthncbor.Unmarshal(ccr.AttestationObject, &p.AttestationObject); err != nil { - return nil, ErrParsingData.WithInfo(err.Error()) + return nil, ErrParsingData.WithInfo(err.Error()).WithError(err) } // Step 8. Perform CBOR decoding on the attestationObject field of the AuthenticatorAttestationResponse // structure to obtain the attestation statement format fmt, the authenticator data authData, and // the attestation statement attStmt. if err = p.AttestationObject.AuthData.Unmarshal(p.AttestationObject.RawAuthData); err != nil { - return nil, fmt.Errorf("error decoding auth data: %v", err) + return nil, err } if !p.AttestationObject.AuthData.Flags.HasAttestedCredentialData() { @@ -114,82 +123,76 @@ func (ccr *AuthenticatorAttestationResponse) Parse() (p *ParsedAttestationRespon // // Steps 9 through 12 are verified against the auth data. These steps are identical to 11 through 14 for assertion so we // handle them with AuthData. -func (attestationObject *AttestationObject) Verify(relyingPartyID string, clientDataHash []byte, verificationRequired bool) error { +func (a *AttestationObject) Verify(relyingPartyID string, clientDataHash []byte, userVerificationRequired bool, mds metadata.Provider) (err error) { rpIDHash := sha256.Sum256([]byte(relyingPartyID)) // Begin Step 9 through 12. Verify that the rpIdHash in authData is the SHA-256 hash of the RP ID expected by the RP. - authDataVerificationError := attestationObject.AuthData.Verify(rpIDHash[:], nil, verificationRequired) - if authDataVerificationError != nil { - return authDataVerificationError + if err = a.AuthData.Verify(rpIDHash[:], nil, userVerificationRequired); err != nil { + return err } + return a.VerifyAttestation(clientDataHash, mds) +} + +// VerifyAttestation only verifies the attestation object excluding the AuthData values. If you wish to also verify the +// AuthData values you should use Verify. +func (a *AttestationObject) VerifyAttestation(clientDataHash []byte, mds metadata.Provider) (err error) { // Step 13. Determine the attestation statement format by performing a // USASCII case-sensitive match on fmt against the set of supported // WebAuthn Attestation Statement Format Identifier values. The up-to-date // list of registered WebAuthn Attestation Statement Format Identifier // values is maintained in the IANA registry of the same name // [WebAuthn-Registries] (https://www.w3.org/TR/webauthn/#biblio-webauthn-registries). - + // // Since there is not an active registry yet, we'll check it against our internal // Supported types. - + // // But first let's make sure attestation is present. If it isn't, we don't need to handle - // any of the following steps - if attestationObject.Format == "none" { - if len(attestationObject.AttStatement) != 0 { + // any of the following steps. + if AttestationFormat(a.Format) == AttestationFormatNone { + if len(a.AttStatement) != 0 { return ErrAttestationFormat.WithInfo("Attestation format none with attestation present") } return nil } - formatHandler, valid := attestationRegistry[attestationObject.Format] - if !valid { - return ErrAttestationFormat.WithInfo(fmt.Sprintf("Attestation format %s is unsupported", attestationObject.Format)) + var ( + handler attestationFormatValidationHandler + valid bool + ) + + if handler, valid = attestationRegistry[AttestationFormat(a.Format)]; !valid { + return ErrAttestationFormat.WithInfo(fmt.Sprintf("Attestation format %s is unsupported", a.Format)) } + var ( + aaguid uuid.UUID + attestationType string + x5cs []any + ) + // Step 14. Verify that attStmt is a correct attestation statement, conveying a valid attestation signature, by using // the attestation statement format fmt’s verification procedure given attStmt, authData and the hash of the serialized // client data computed in step 7. - attestationType, x5c, err := formatHandler(*attestationObject, clientDataHash) - if err != nil { + if attestationType, x5cs, err = handler(*a, clientDataHash, mds); err != nil { return err.(*Error).WithInfo(attestationType) } - aaguid, err := uuid.FromBytes(attestationObject.AuthData.AttData.AAGUID) - if err != nil { - return err + if len(a.AuthData.AttData.AAGUID) != 0 { + if aaguid, err = uuid.FromBytes(a.AuthData.AttData.AAGUID); err != nil { + return ErrInvalidAttestation.WithInfo("Error occurred parsing AAGUID during attestation validation").WithDetails(err.Error()).WithError(err) + } } - if meta, ok := metadata.Metadata[aaguid]; ok { - for _, s := range meta.StatusReports { - if metadata.IsUndesiredAuthenticatorStatus(s.Status) { - return ErrInvalidAttestation.WithDetails("Authenticator with undesirable status encountered") - } - } + if mds == nil { + return nil + } - if x5c != nil { - x5cAtt, err := x509.ParseCertificate(x5c[0].([]byte)) - if err != nil { - return ErrInvalidAttestation.WithDetails("Unable to parse attestation certificate from x5c") - } - - if x5cAtt.Subject.CommonName != x5cAtt.Issuer.CommonName { - var hasBasicFull = false - - for _, a := range meta.MetadataStatement.AttestationTypes { - if a == metadata.BasicFull || a == metadata.AttCA { - hasBasicFull = true - } - } - - if !hasBasicFull { - return ErrInvalidAttestation.WithDetails("Attestation with full attestation from authenticator that does not support full attestation") - } - } - } - } else if metadata.Conformance { - return ErrInvalidAttestation.WithDetails(fmt.Sprintf("AAGUID %s not found in metadata during conformance testing", aaguid.String())) + var protoErr *Error + + if protoErr = ValidateMetadata(context.Background(), mds, aaguid, attestationType, x5cs); protoErr != nil { + return ErrInvalidAttestation.WithInfo(fmt.Sprintf("Error occurred validating metadata during attestation validation: %+v", protoErr)).WithDetails(protoErr.DevInfo).WithError(protoErr) } return nil diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/attestation_androidkey.go b/vendor/github.com/go-webauthn/webauthn/protocol/attestation_androidkey.go index de437839523326cb9b8631e03d5dfbef0a1a8a02..7bfff7eaaea1893c2c53a6cbef7d23e6e3918b98 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/attestation_androidkey.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/attestation_androidkey.go @@ -10,10 +10,8 @@ import ( "github.com/go-webauthn/webauthn/protocol/webauthncose" ) -var androidAttestationKey = "android-key" - func init() { - RegisterAttestationFormat(androidAttestationKey, verifyAndroidKeyFormat) + RegisterAttestationFormat(AttestationFormatAndroidKey, verifyAndroidKeyFormat) } // The android-key attestation statement looks like: @@ -31,26 +29,26 @@ func init() { // } // // Specification: §8.4. Android Key Attestation Statement Format (https://www.w3.org/TR/webauthn/#sctn-android-key-attestation) -func verifyAndroidKeyFormat(att AttestationObject, clientDataHash []byte) (string, []interface{}, error) { +func verifyAndroidKeyFormat(att AttestationObject, clientDataHash []byte, _ metadata.Provider) (string, []any, error) { // Given the verification procedure inputs attStmt, authenticatorData and clientDataHash, the verification procedure is as follows: // §8.4.1. Verify that attStmt is valid CBOR conforming to the syntax defined above and perform CBOR decoding on it to extract // the contained fields. // Get the alg value - A COSEAlgorithmIdentifier containing the identifier of the algorithm // used to generate the attestation signature. - alg, present := att.AttStatement["alg"].(int64) + alg, present := att.AttStatement[stmtAlgorithm].(int64) if !present { return "", nil, ErrAttestationFormat.WithDetails("Error retrieving alg value") } // Get the sig value - A byte string containing the attestation signature. - sig, present := att.AttStatement["sig"].([]byte) + sig, present := att.AttStatement[stmtSignature].([]byte) if !present { return "", nil, ErrAttestationFormat.WithDetails("Error retrieving sig value") } // If x5c is not present, return an error - x5c, x509present := att.AttStatement["x5c"].([]interface{}) + x5c, x509present := att.AttStatement[stmtX5C].([]any) if !x509present { // Handle Basic Attestation steps for the x509 Certificate return "", nil, ErrAttestationFormat.WithDetails("Error retrieving x5c value") @@ -67,27 +65,25 @@ func verifyAndroidKeyFormat(att AttestationObject, clientDataHash []byte) (strin attCert, err := x509.ParseCertificate(attCertBytes) if err != nil { - return "", nil, ErrAttestationFormat.WithDetails(fmt.Sprintf("Error parsing certificate from ASN.1 data: %+v", err)) + return "", nil, ErrAttestationFormat.WithDetails(fmt.Sprintf("Error parsing certificate from ASN.1 data: %+v", err)).WithError(err) } coseAlg := webauthncose.COSEAlgorithmIdentifier(alg) - sigAlg := webauthncose.SigAlgFromCOSEAlg(coseAlg) - - if err = attCert.CheckSignature(x509.SignatureAlgorithm(sigAlg), signatureData, sig); err != nil { - return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Signature validation error: %+v\n", err)) + if err = attCert.CheckSignature(webauthncose.SigAlgFromCOSEAlg(coseAlg), signatureData, sig); err != nil { + return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Signature validation error: %+v\n", err)).WithError(err) } // Verify that the public key in the first certificate in x5c matches the credentialPublicKey in the attestedCredentialData in authenticatorData. pubKey, err := webauthncose.ParsePublicKey(att.AuthData.AttData.CredentialPublicKey) if err != nil { - return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error parsing public key: %+v\n", err)) + return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error parsing public key: %+v\n", err)).WithError(err) } e := pubKey.(webauthncose.EC2PublicKeyData) valid, err = e.Verify(signatureData, sig) if err != nil || !valid { - return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error parsing public key: %+v\n", err)) + return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error parsing public key: %+v\n", err)).WithError(err) } // §8.4.3. Verify that the attestationChallenge field in the attestation certificate extension data is identical to clientDataHash. @@ -109,11 +105,11 @@ func verifyAndroidKeyFormat(att AttestationObject, clientDataHash []byte) (strin decoded := keyDescription{} if _, err = asn1.Unmarshal(attExtBytes, &decoded); err != nil { - return "", nil, ErrAttestationFormat.WithDetails("Unable to parse Android key attestation certificate extensions") + return "", nil, ErrAttestationFormat.WithDetails("Unable to parse Android key attestation certificate extensions").WithError(err) } // Verify that the attestationChallenge field in the attestation certificate extension data is identical to clientDataHash. - if 0 != bytes.Compare(decoded.AttestationChallenge, clientDataHash) { + if bytes.Compare(decoded.AttestationChallenge, clientDataHash) != 0 { return "", nil, ErrAttestationFormat.WithDetails("Attestation challenge not equal to clientDataHash") } @@ -165,19 +161,19 @@ type authorizationList struct { Padding []int `asn1:"tag:6,explicit,set,optional"` EcCurve int `asn1:"tag:10,explicit,optional"` RsaPublicExponent int `asn1:"tag:200,explicit,optional"` - RollbackResistance interface{} `asn1:"tag:303,explicit,optional"` + RollbackResistance any `asn1:"tag:303,explicit,optional"` ActiveDateTime int `asn1:"tag:400,explicit,optional"` OriginationExpireDateTime int `asn1:"tag:401,explicit,optional"` UsageExpireDateTime int `asn1:"tag:402,explicit,optional"` - NoAuthRequired interface{} `asn1:"tag:503,explicit,optional"` + NoAuthRequired any `asn1:"tag:503,explicit,optional"` UserAuthType int `asn1:"tag:504,explicit,optional"` AuthTimeout int `asn1:"tag:505,explicit,optional"` - AllowWhileOnBody interface{} `asn1:"tag:506,explicit,optional"` - TrustedUserPresenceRequired interface{} `asn1:"tag:507,explicit,optional"` - TrustedConfirmationRequired interface{} `asn1:"tag:508,explicit,optional"` - UnlockedDeviceRequired interface{} `asn1:"tag:509,explicit,optional"` - AllApplications interface{} `asn1:"tag:600,explicit,optional"` - ApplicationID interface{} `asn1:"tag:601,explicit,optional"` + AllowWhileOnBody any `asn1:"tag:506,explicit,optional"` + TrustedUserPresenceRequired any `asn1:"tag:507,explicit,optional"` + TrustedConfirmationRequired any `asn1:"tag:508,explicit,optional"` + UnlockedDeviceRequired any `asn1:"tag:509,explicit,optional"` + AllApplications any `asn1:"tag:600,explicit,optional"` + ApplicationID any `asn1:"tag:601,explicit,optional"` CreationDateTime int `asn1:"tag:701,explicit,optional"` Origin int `asn1:"tag:702,explicit,optional"` RootOfTrust rootOfTrust `asn1:"tag:704,explicit,optional"` diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/attestation_apple.go b/vendor/github.com/go-webauthn/webauthn/protocol/attestation_apple.go index 935218f29920159615779f6f48a7589becbaad04..e2b3e9edfd916840e6e32900f7bf043fbb238cc3 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/attestation_apple.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/attestation_apple.go @@ -14,10 +14,8 @@ import ( "github.com/go-webauthn/webauthn/protocol/webauthncose" ) -var appleAttestationKey = "apple" - func init() { - RegisterAttestationFormat(appleAttestationKey, verifyAppleFormat) + RegisterAttestationFormat(AttestationFormatApple, verifyAppleFormat) } // The apple attestation statement looks like: @@ -33,12 +31,11 @@ func init() { // } // // Specification: §8.8. Apple Anonymous Attestation Statement Format (https://www.w3.org/TR/webauthn/#sctn-apple-anonymous-attestation) -func verifyAppleFormat(att AttestationObject, clientDataHash []byte) (string, []interface{}, error) { +func verifyAppleFormat(att AttestationObject, clientDataHash []byte, _ metadata.Provider) (string, []any, error) { // Step 1. Verify that attStmt is valid CBOR conforming to the syntax defined // above and perform CBOR decoding on it to extract the contained fields. - - // If x5c is not present, return an error - x5c, x509present := att.AttStatement["x5c"].([]interface{}) + // If x5c is not present, return an error. + x5c, x509present := att.AttStatement[stmtX5C].([]any) if !x509present { // Handle Basic Attestation steps for the x509 Certificate return "", nil, ErrAttestationFormat.WithDetails("Error retrieving x5c value") @@ -51,7 +48,7 @@ func verifyAppleFormat(att AttestationObject, clientDataHash []byte) (string, [] credCert, err := x509.ParseCertificate(credCertBytes) if err != nil { - return "", nil, ErrAttestationFormat.WithDetails(fmt.Sprintf("Error parsing certificate from ASN.1 data: %+v", err)) + return "", nil, ErrAttestationFormat.WithDetails(fmt.Sprintf("Error parsing certificate from ASN.1 data: %+v", err)).WithError(err) } // Step 2. Concatenate authenticatorData and clientDataHash to form nonceToHash. @@ -76,10 +73,10 @@ func verifyAppleFormat(att AttestationObject, clientDataHash []byte) (string, [] decoded := AppleAnonymousAttestation{} if _, err = asn1.Unmarshal(attExtBytes, &decoded); err != nil { - return "", nil, ErrAttestationFormat.WithDetails("Unable to parse apple attestation certificate extensions") + return "", nil, ErrAttestationFormat.WithDetails("Unable to parse apple attestation certificate extensions").WithError(err) } - if !bytes.Equal(decoded.Nonce, nonce[:]) || err != nil { + if !bytes.Equal(decoded.Nonce, nonce[:]) { return "", nil, ErrInvalidAttestation.WithDetails("Attestation certificate does not contain expected nonce") } @@ -87,7 +84,7 @@ func verifyAppleFormat(att AttestationObject, clientDataHash []byte) (string, [] // TODO: Probably move this part to webauthncose.go pubKey, err := webauthncose.ParsePublicKey(att.AuthData.AttData.CredentialPublicKey) if err != nil { - return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error parsing public key: %+v\n", err)) + return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error parsing public key: %+v\n", err)).WithError(err) } credPK := pubKey.(webauthncose.EC2PublicKeyData) @@ -106,7 +103,8 @@ func verifyAppleFormat(att AttestationObject, clientDataHash []byte) (string, [] return string(metadata.AnonCA), x5c, nil } -// Apple has not yet publish schema for the extension(as of JULY 2021.) +// AppleAnonymousAttestation represents the attestation format for Apple, who have not yet published a schema for the +// extension (as of JULY 2021.) type AppleAnonymousAttestation struct { Nonce []byte `asn1:"tag:1,explicit"` } diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/attestation_packed.go b/vendor/github.com/go-webauthn/webauthn/protocol/attestation_packed.go index 8b0940a4bdcba04c1d5aa42efad7b54726c3fae1..8f299eb946511e67a5fccc65746d6db0f51e0917 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/attestation_packed.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/attestation_packed.go @@ -12,10 +12,8 @@ import ( "github.com/go-webauthn/webauthn/protocol/webauthncose" ) -var packedAttestationKey = "packed" - func init() { - RegisterAttestationFormat(packedAttestationKey, verifyPackedFormat) + RegisterAttestationFormat(AttestationFormatPacked, verifyPackedFormat) } // The packed attestation statement looks like: @@ -36,26 +34,24 @@ func init() { // } // // Specification: §8.2. Packed Attestation Statement Format (https://www.w3.org/TR/webauthn/#sctn-packed-attestation) -func verifyPackedFormat(att AttestationObject, clientDataHash []byte) (string, []interface{}, error) { +func verifyPackedFormat(att AttestationObject, clientDataHash []byte, _ metadata.Provider) (string, []any, error) { // Step 1. Verify that attStmt is valid CBOR conforming to the syntax defined // above and perform CBOR decoding on it to extract the contained fields. - // Get the alg value - A COSEAlgorithmIdentifier containing the identifier of the algorithm // used to generate the attestation signature. - - alg, present := att.AttStatement["alg"].(int64) + alg, present := att.AttStatement[stmtAlgorithm].(int64) if !present { - return packedAttestationKey, nil, ErrAttestationFormat.WithDetails("Error retrieving alg value") + return string(AttestationFormatPacked), nil, ErrAttestationFormat.WithDetails("Error retrieving alg value") } // Get the sig value - A byte string containing the attestation signature. - sig, present := att.AttStatement["sig"].([]byte) + sig, present := att.AttStatement[stmtSignature].([]byte) if !present { - return packedAttestationKey, nil, ErrAttestationFormat.WithDetails("Error retrieving sig value") + return string(AttestationFormatPacked), nil, ErrAttestationFormat.WithDetails("Error retrieving sig value") } // Step 2. If x5c is present, this indicates that the attestation type is not ECDAA. - x5c, x509present := att.AttStatement["x5c"].([]interface{}) + x5c, x509present := att.AttStatement[stmtX5C].([]any) if x509present { // Handle Basic Attestation steps for the x509 Certificate return handleBasicAttestation(sig, clientDataHash, att.RawAuthData, att.AuthData.AttData.AAGUID, alg, x5c) @@ -63,7 +59,7 @@ func verifyPackedFormat(att AttestationObject, clientDataHash []byte) (string, [ // Step 3. If ecdaaKeyId is present, then the attestation type is ECDAA. // Also make sure the we did not have an x509 then - ecdaaKeyID, ecdaaKeyPresent := att.AttStatement["ecdaaKeyId"].([]byte) + ecdaaKeyID, ecdaaKeyPresent := att.AttStatement[stmtECDAAKID].([]byte) if ecdaaKeyPresent { // Handle ECDAA Attestation steps for the x509 Certificate return handleECDAAAttestation(sig, clientDataHash, ecdaaKeyID) @@ -74,7 +70,7 @@ func verifyPackedFormat(att AttestationObject, clientDataHash []byte) (string, [ } // Handle the attestation steps laid out in -func handleBasicAttestation(signature, clientDataHash, authData, aaguid []byte, alg int64, x5c []interface{}) (string, []interface{}, error) { +func handleBasicAttestation(signature, clientDataHash, authData, aaguid []byte, alg int64, x5c []any) (string, []any, error) { // Step 2.1. Verify that sig is a valid signature over the concatenation of authenticatorData // and clientDataHash using the attestation public key in attestnCert with the algorithm specified in alg. for _, c := range x5c { @@ -85,7 +81,7 @@ func handleBasicAttestation(signature, clientDataHash, authData, aaguid []byte, ct, err := x509.ParseCertificate(cb) if err != nil { - return "", x5c, ErrAttestationFormat.WithDetails(fmt.Sprintf("Error parsing certificate from ASN.1 data: %+v", err)) + return "", x5c, ErrAttestationFormat.WithDetails(fmt.Sprintf("Error parsing certificate from ASN.1 data: %+v", err)).WithError(err) } if ct.NotBefore.After(time.Now()) || ct.NotAfter.Before(time.Now()) { @@ -102,14 +98,12 @@ func handleBasicAttestation(signature, clientDataHash, authData, aaguid []byte, attCert, err := x509.ParseCertificate(attCertBytes) if err != nil { - return "", x5c, ErrAttestationFormat.WithDetails(fmt.Sprintf("Error parsing certificate from ASN.1 data: %+v", err)) + return "", x5c, ErrAttestationFormat.WithDetails(fmt.Sprintf("Error parsing certificate from ASN.1 data: %+v", err)).WithError(err) } coseAlg := webauthncose.COSEAlgorithmIdentifier(alg) - sigAlg := webauthncose.SigAlgFromCOSEAlg(coseAlg) - - if err = attCert.CheckSignature(x509.SignatureAlgorithm(sigAlg), signatureData, signature); err != nil { - return "", x5c, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Signature validation error: %+v\n", err)) + if err = attCert.CheckSignature(webauthncose.SigAlgFromCOSEAlg(coseAlg), signatureData, signature); err != nil { + return "", x5c, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Signature validation error: %+v\n", err)).WithError(err) } // Step 2.2 Verify that attestnCert meets the requirements in §8.2.1 Packed attestation statement certificate requirements. @@ -201,15 +195,11 @@ func handleBasicAttestation(signature, clientDataHash, authData, aaguid []byte, return string(metadata.BasicFull), x5c, nil } -func handleECDAAAttestation(signature, clientDataHash, ecdaaKeyID []byte) (string, []interface{}, error) { +func handleECDAAAttestation(signature, clientDataHash, ecdaaKeyID []byte) (string, []any, error) { return "Packed (ECDAA)", nil, ErrNotSpecImplemented } -func handleSelfAttestation(alg int64, pubKey, authData, clientDataHash, signature []byte) (string, []interface{}, error) { - // §4.1 Validate that alg matches the algorithm of the credentialPublicKey in authenticatorData. - - // §4.2 Verify that sig is a valid signature over the concatenation of authenticatorData and - // clientDataHash using the credential public key with alg. +func handleSelfAttestation(alg int64, pubKey, authData, clientDataHash, signature []byte) (string, []any, error) { verificationData := append(authData, clientDataHash...) key, err := webauthncose.ParsePublicKey(pubKey) @@ -217,6 +207,7 @@ func handleSelfAttestation(alg int64, pubKey, authData, clientDataHash, signatur return "", nil, ErrAttestationFormat.WithDetails(fmt.Sprintf("Error parsing the public key: %+v\n", err)) } + // §4.1 Validate that alg matches the algorithm of the credentialPublicKey in authenticatorData. switch k := key.(type) { case webauthncose.OKPPublicKeyData: err = verifyKeyAlgorithm(k.Algorithm, alg) @@ -232,6 +223,8 @@ func handleSelfAttestation(alg int64, pubKey, authData, clientDataHash, signatur return "", nil, err } + // §4.2 Verify that sig is a valid signature over the concatenation of authenticatorData and + // clientDataHash using the credential public key with alg. valid, err := webauthncose.VerifySignature(key, verificationData, signature) if !valid && err == nil { return "", nil, ErrInvalidAttestation.WithDetails("Unable to verify signature") diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/attestation_safetynet.go b/vendor/github.com/go-webauthn/webauthn/protocol/attestation_safetynet.go index 8e94ad187d07dc9a21af28283737a50bd3f706a0..7355c97da3954e52c63812034df36a0aa0db7a00 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/attestation_safetynet.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/attestation_safetynet.go @@ -2,6 +2,7 @@ package protocol import ( "bytes" + "context" "crypto/sha256" "crypto/x509" "encoding/base64" @@ -14,20 +15,18 @@ import ( "github.com/go-webauthn/webauthn/metadata" ) -var safetyNetAttestationKey = "android-safetynet" - func init() { - RegisterAttestationFormat(safetyNetAttestationKey, verifySafetyNetFormat) + RegisterAttestationFormat(AttestationFormatAndroidSafetyNet, verifySafetyNetFormat) } type SafetyNetResponse struct { - Nonce string `json:"nonce"` - TimestampMs int64 `json:"timestampMs"` - ApkPackageName string `json:"apkPackageName"` - ApkDigestSha256 string `json:"apkDigestSha256"` - CtsProfileMatch bool `json:"ctsProfileMatch"` - ApkCertificateDigestSha256 []interface{} `json:"apkCertificateDigestSha256"` - BasicIntegrity bool `json:"basicIntegrity"` + Nonce string `json:"nonce"` + TimestampMs int64 `json:"timestampMs"` + ApkPackageName string `json:"apkPackageName"` + ApkDigestSha256 string `json:"apkDigestSha256"` + CtsProfileMatch bool `json:"ctsProfileMatch"` + ApkCertificateDigestSha256 []any `json:"apkCertificateDigestSha256"` + BasicIntegrity bool `json:"basicIntegrity"` } // Thanks to @koesie10 and @herrjemand for outlining how to support this type really well @@ -42,7 +41,7 @@ type SafetyNetResponse struct { // authenticators SHOULD make use of the Android Key Attestation when available, even if the SafetyNet API is also present. // // Specification: §8.5. Android SafetyNet Attestation Statement Format (https://www.w3.org/TR/webauthn/#sctn-android-safetynet-attestation) -func verifySafetyNetFormat(att AttestationObject, clientDataHash []byte) (string, []interface{}, error) { +func verifySafetyNetFormat(att AttestationObject, clientDataHash []byte, mds metadata.Provider) (string, []any, error) { // The syntax of an Android Attestation statement is defined as follows: // $$attStmtType //= ( // fmt: "android-safetynet", @@ -59,7 +58,7 @@ func verifySafetyNetFormat(att AttestationObject, clientDataHash []byte) (string // We have done this // §8.5.2 Verify that response is a valid SafetyNet response of version ver. - version, present := att.AttStatement["ver"].(string) + version, present := att.AttStatement[stmtVersion].(string) if !present { return "", nil, ErrAttestationFormat.WithDetails("Unable to find the version of SafetyNet") } @@ -75,8 +74,8 @@ func verifySafetyNetFormat(att AttestationObject, clientDataHash []byte) (string return "", nil, ErrAttestationFormat.WithDetails("Unable to find the SafetyNet response") } - token, err := jwt.Parse(string(response), func(token *jwt.Token) (interface{}, error) { - chain := token.Header["x5c"].([]interface{}) + token, err := jwt.Parse(string(response), func(token *jwt.Token) (any, error) { + chain := token.Header[stmtX5C].([]any) o := make([]byte, base64.StdEncoding.DecodedLen(len(chain[0].(string)))) @@ -86,18 +85,19 @@ func verifySafetyNetFormat(att AttestationObject, clientDataHash []byte) (string } cert, err := x509.ParseCertificate(o[:n]) + return cert.PublicKey, err }) if err != nil { - return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error finding cert issued to correct hostname: %+v", err)) + return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error finding cert issued to correct hostname: %+v", err)).WithError(err) } // marshall the JWT payload into the safetynet response json var safetyNetResponse SafetyNetResponse if err = mapstructure.Decode(token.Claims, &safetyNetResponse); err != nil { - return "", nil, ErrAttestationFormat.WithDetails(fmt.Sprintf("Error parsing the SafetyNet response: %+v", err)) + return "", nil, ErrAttestationFormat.WithDetails(fmt.Sprintf("Error parsing the SafetyNet response: %+v", err)).WithError(err) } // §8.5.3 Verify that the nonce in the response is identical to the Base64 encoding of the SHA-256 hash of the concatenation @@ -106,27 +106,27 @@ func verifySafetyNetFormat(att AttestationObject, clientDataHash []byte) (string nonceBytes, err := base64.StdEncoding.DecodeString(safetyNetResponse.Nonce) if !bytes.Equal(nonceBuffer[:], nonceBytes) || err != nil { - return "", nil, ErrInvalidAttestation.WithDetails("Invalid nonce for in SafetyNet response") + return "", nil, ErrInvalidAttestation.WithDetails("Invalid nonce for in SafetyNet response").WithError(err) } // §8.5.4 Let attestationCert be the attestation certificate (https://www.w3.org/TR/webauthn/#attestation-certificate) - certChain := token.Header["x5c"].([]interface{}) + certChain := token.Header[stmtX5C].([]any) l := make([]byte, base64.StdEncoding.DecodedLen(len(certChain[0].(string)))) n, err := base64.StdEncoding.Decode(l, []byte(certChain[0].(string))) if err != nil { - return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error finding cert issued to correct hostname: %+v", err)) + return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error finding cert issued to correct hostname: %+v", err)).WithError(err) } attestationCert, err := x509.ParseCertificate(l[:n]) if err != nil { - return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error finding cert issued to correct hostname: %+v", err)) + return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error finding cert issued to correct hostname: %+v", err)).WithError(err) } // §8.5.5 Verify that attestationCert is issued to the hostname "attest.android.com" err = attestationCert.VerifyHostname("attest.android.com") if err != nil { - return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error finding cert issued to correct hostname: %+v", err)) + return "", nil, ErrInvalidAttestation.WithDetails(fmt.Sprintf("Error finding cert issued to correct hostname: %+v", err)).WithError(err) } // §8.5.6 Verify that the ctsProfileMatch attribute in the payload of response is true. @@ -134,19 +134,13 @@ func verifySafetyNetFormat(att AttestationObject, clientDataHash []byte) (string return "", nil, ErrInvalidAttestation.WithDetails("ctsProfileMatch attribute of the JWT payload is false") } - // Verify sanity of timestamp in the payload - now := time.Now() - oneMinuteAgo := now.Add(-time.Minute) - - if t := time.Unix(safetyNetResponse.TimestampMs/1000, 0); t.After(now) { - // zero tolerance for post-dated timestamps + if t := time.Unix(safetyNetResponse.TimestampMs/1000, 0); t.After(time.Now()) { + // Zero tolerance for post-dated timestamps. return "", nil, ErrInvalidAttestation.WithDetails("SafetyNet response with timestamp after current time") - } else if t.Before(oneMinuteAgo) { - // allow old timestamp for testing purposes - // TODO: Make this user configurable - msg := "SafetyNet response with timestamp before one minute ago" - if metadata.Conformance { - return "", nil, ErrInvalidAttestation.WithDetails(msg) + } else if t.Before(time.Now().Add(-time.Minute)) { + // Small tolerance for pre-dated timestamps. + if mds != nil && mds.GetValidateEntry(context.Background()) { + return "", nil, ErrInvalidAttestation.WithDetails("SafetyNet response with timestamp before one minute ago") } } diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/attestation_tpm.go b/vendor/github.com/go-webauthn/webauthn/protocol/attestation_tpm.go index 892bdd81b629f77b0a5d3adb07c3a5253e9d1693..b2132ea58bfbb3d88461f6fe31fac742dd33c4ad 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/attestation_tpm.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/attestation_tpm.go @@ -15,20 +15,18 @@ import ( "github.com/go-webauthn/webauthn/protocol/webauthncose" ) -var tpmAttestationKey = "tpm" - func init() { - RegisterAttestationFormat(tpmAttestationKey, verifyTPMFormat) + RegisterAttestationFormat(AttestationFormatTPM, verifyTPMFormat) } -func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []interface{}, error) { +func verifyTPMFormat(att AttestationObject, clientDataHash []byte, _ metadata.Provider) (string, []any, error) { // Given the verification procedure inputs attStmt, authenticatorData // and clientDataHash, the verification procedure is as follows // Verify that attStmt is valid CBOR conforming to the syntax defined // above and perform CBOR decoding on it to extract the contained fields - ver, present := att.AttStatement["ver"].(string) + ver, present := att.AttStatement[stmtVersion].(string) if !present { return "", nil, ErrAttestationFormat.WithDetails("Error retrieving ver value") } @@ -37,35 +35,35 @@ func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []in return "", nil, ErrAttestationFormat.WithDetails("WebAuthn only supports TPM 2.0 currently") } - alg, present := att.AttStatement["alg"].(int64) + alg, present := att.AttStatement[stmtAlgorithm].(int64) if !present { return "", nil, ErrAttestationFormat.WithDetails("Error retrieving alg value") } coseAlg := webauthncose.COSEAlgorithmIdentifier(alg) - x5c, x509present := att.AttStatement["x5c"].([]interface{}) + x5c, x509present := att.AttStatement[stmtX5C].([]any) if !x509present { // Handle Basic Attestation steps for the x509 Certificate return "", nil, ErrNotImplemented } - _, ecdaaKeyPresent := att.AttStatement["ecdaaKeyId"].([]byte) + _, ecdaaKeyPresent := att.AttStatement[stmtECDAAKID].([]byte) if ecdaaKeyPresent { return "", nil, ErrNotImplemented } - sigBytes, present := att.AttStatement["sig"].([]byte) + sigBytes, present := att.AttStatement[stmtSignature].([]byte) if !present { return "", nil, ErrAttestationFormat.WithDetails("Error retrieving sig value") } - certInfoBytes, present := att.AttStatement["certInfo"].([]byte) + certInfoBytes, present := att.AttStatement[stmtCertInfo].([]byte) if !present { return "", nil, ErrAttestationFormat.WithDetails("Error retrieving certInfo value") } - pubAreaBytes, present := att.AttStatement["pubArea"].([]byte) + pubAreaBytes, present := att.AttStatement[stmtPubArea].([]byte) if !present { return "", nil, ErrAttestationFormat.WithDetails("Error retrieving pubArea value") } @@ -74,7 +72,7 @@ func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []in // is identical to the credentialPublicKey in the attestedCredentialData in authenticatorData. pubArea, err := tpm2.DecodePublic(pubAreaBytes) if err != nil { - return "", nil, ErrAttestationFormat.WithDetails("Unable to decode TPMT_PUBLIC in attestation statement") + return "", nil, ErrAttestationFormat.WithDetails("Unable to decode TPMT_PUBLIC in attestation statement").WithError(err) } key, err := webauthncose.ParsePublicKey(att.AuthData.AttData.CredentialPublicKey) @@ -115,10 +113,9 @@ func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []in } // 3/4 Verify that extraData is set to the hash of attToBeSigned using the hash algorithm employed in "alg". - f := webauthncose.HasherFromCOSEAlg(coseAlg) - h := f() - + h := webauthncose.HasherFromCOSEAlg(coseAlg) h.Write(attToBeSigned) + if !bytes.Equal(certInfo.ExtraData, h.Sum(nil)) { return "", nil, ErrAttestationFormat.WithDetails("ExtraData is not set to hash of attToBeSigned") } @@ -149,15 +146,13 @@ func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []in return "", nil, ErrAttestation.WithDetails("Error getting certificate from x5c cert chain") } - aikCert, err := x509.ParseCertificate(aikCertBytes) - if err != nil { + var aikCert *x509.Certificate + + if aikCert, err = x509.ParseCertificate(aikCertBytes); err != nil { return "", nil, ErrAttestationFormat.WithDetails("Error parsing certificate from ASN.1") } - sigAlg := webauthncose.SigAlgFromCOSEAlg(coseAlg) - - err = aikCert.CheckSignature(x509.SignatureAlgorithm(sigAlg), certInfoBytes, sigBytes) - if err != nil { + if err = aikCert.CheckSignature(webauthncose.SigAlgFromCOSEAlg(coseAlg), certInfoBytes, sigBytes); err != nil { return "", nil, ErrAttestationFormat.WithDetails(fmt.Sprintf("Signature validation error: %+v\n", err)) } // Verify that aikCert meets the requirements in §8.3.1 TPM Attestation Statement Certificate Requirements @@ -166,23 +161,41 @@ func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []in if aikCert.Version != 3 { return "", nil, ErrAttestationFormat.WithDetails("AIK certificate version must be 3") } + // 2/6 Subject field MUST be set to empty. if aikCert.Subject.String() != "" { return "", nil, ErrAttestationFormat.WithDetails("AIK certificate subject must be empty") } - // 3/6 The Subject Alternative Name extension MUST be set as defined in [TPMv2-EK-Profile] section 3.2.9{} - var manufacturer, model, version string + var ( + manufacturer, model, version string + ekuValid = false + eku []asn1.ObjectIdentifier + constraints tpmBasicConstraints + rest []byte + ) for _, ext := range aikCert.Extensions { - if ext.Id.Equal([]int{2, 5, 29, 17}) { - manufacturer, model, version, err = parseSANExtension(ext.Value) - if err != nil { + if ext.Id.Equal(oidExtensionSubjectAltName) { + if manufacturer, model, version, err = parseSANExtension(ext.Value); err != nil { return "", nil, err } + } else if ext.Id.Equal(oidExtensionExtendedKeyUsage) { + if rest, err = asn1.Unmarshal(ext.Value, &eku); len(rest) != 0 || err != nil || !eku[0].Equal(tcgKpAIKCertificate) { + return "", nil, ErrAttestationFormat.WithDetails("AIK certificate EKU missing 2.23.133.8.3") + } + + ekuValid = true + } else if ext.Id.Equal(oidExtensionBasicConstraints) { + if rest, err = asn1.Unmarshal(ext.Value, &constraints); err != nil { + return "", nil, ErrAttestationFormat.WithDetails("AIK certificate basic constraints malformed") + } else if len(rest) != 0 { + return "", nil, ErrAttestationFormat.WithDetails("AIK certificate basic constraints contains extra data") + } } } + // 3/6 The Subject Alternative Name extension MUST be set as defined in [TPMv2-EK-Profile] section 3.2.9{} if manufacturer == "" || model == "" || version == "" { return "", nil, ErrAttestationFormat.WithDetails("Invalid SAN data in AIK certificate") } @@ -192,44 +205,10 @@ func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []in } // 4/6 The Extended Key Usage extension MUST contain the "joint-iso-itu-t(2) internationalorganizations(23) 133 tcg-kp(8) tcg-kp-AIKCertificate(3)" OID. - var ( - ekuValid = false - eku []asn1.ObjectIdentifier - ) - - for _, ext := range aikCert.Extensions { - if ext.Id.Equal([]int{2, 5, 29, 37}) { - rest, err := asn1.Unmarshal(ext.Value, &eku) - if len(rest) != 0 || err != nil || !eku[0].Equal(tcgKpAIKCertificate) { - return "", nil, ErrAttestationFormat.WithDetails("AIK certificate EKU missing 2.23.133.8.3") - } - - ekuValid = true - } - } - if !ekuValid { return "", nil, ErrAttestationFormat.WithDetails("AIK certificate missing EKU") } - // 5/6 The Basic Constraints extension MUST have the CA component set to false. - type basicConstraints struct { - IsCA bool `asn1:"optional"` - MaxPathLen int `asn1:"optional,default:-1"` - } - - var constraints basicConstraints - - for _, ext := range aikCert.Extensions { - if ext.Id.Equal([]int{2, 5, 29, 19}) { - if rest, err := asn1.Unmarshal(ext.Value, &constraints); err != nil { - return "", nil, ErrAttestationFormat.WithDetails("AIK certificate basic constraints malformed") - } else if len(rest) != 0 { - return "", nil, ErrAttestationFormat.WithDetails("AIK certificate basic constraints contains extra data") - } - } - } - // 6/6 An Authority Information Access (AIA) extension with entry id-ad-ocsp and a CRL Distribution Point // extension [RFC5280] are both OPTIONAL as the status of many attestation certificates is available // through metadata services. See, for example, the FIDO Metadata Service. @@ -241,23 +220,24 @@ func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []in return string(metadata.AttCA), x5c, err } +// forEachSAN loops through the TPM SAN extension. +// +// RFC 5280, 4.2.1.6 +// SubjectAltName ::= GeneralNames +// +// GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName +// +// GeneralName ::= CHOICE { +// otherName [0] OtherName, +// rfc822Name [1] IA5String, +// dNSName [2] IA5String, +// x400Address [3] ORAddress, +// directoryName [4] Name, +// ediPartyName [5] EDIPartyName, +// uniformResourceIdentifier [6] IA5String, +// iPAddress [7] OCTET STRING, +// registeredID [8] OBJECT IDENTIFIER } func forEachSAN(extension []byte, callback func(tag int, data []byte) error) error { - // RFC 5280, 4.2.1.6 - - // SubjectAltName ::= GeneralNames - // - // GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName - // - // GeneralName ::= CHOICE { - // otherName [0] OtherName, - // rfc822Name [1] IA5String, - // dNSName [2] IA5String, - // x400Address [3] ORAddress, - // directoryName [4] Name, - // ediPartyName [5] EDIPartyName, - // uniformResourceIdentifier [6] IA5String, - // iPAddress [7] OCTET STRING, - // registeredID [8] OBJECT IDENTIFIER } var seq asn1.RawValue rest, err := asn1.Unmarshal(extension, &seq) @@ -306,13 +286,16 @@ func parseSANExtension(value []byte) (manufacturer string, model string, version case nameTypeDN: tpmDeviceAttributes := pkix.RDNSequence{} _, err := asn1.Unmarshal(data, &tpmDeviceAttributes) + if err != nil { return err } + for _, rdn := range tpmDeviceAttributes { if len(rdn) == 0 { continue } + for _, atv := range rdn { value, ok := atv.Value.(string) if !ok { @@ -322,15 +305,18 @@ func parseSANExtension(value []byte) (manufacturer string, model string, version if atv.Type.Equal(tcgAtTpmManufacturer) { manufacturer = strings.TrimPrefix(value, "id:") } + if atv.Type.Equal(tcgAtTpmModel) { model = value } + if atv.Type.Equal(tcgAtTpmVersion) { version = strings.TrimPrefix(value, "id:") } } } } + return nil }) @@ -343,23 +329,34 @@ var tpmManufacturers = []struct { code string }{ {"414D4400", "AMD", "AMD"}, + {"414E5400", "Ant Group", "ANT"}, {"41544D4C", "Atmel", "ATML"}, {"4252434D", "Broadcom", "BRCM"}, + {"4353434F", "Cisco", "CSCO"}, + {"464C5953", "Flyslice Technologies", "FLYS"}, + {"524F4343", "Fuzhou Rockchip", "ROCC"}, + {"474F4F47", "Google", "GOOG"}, + {"48504900", "HPI", "HPI"}, + {"48504500", "HPE", "HPE"}, + {"48495349", "Huawei", "HISI"}, {"49424d00", "IBM", "IBM"}, + {"49424D00", "IBM", "IBM"}, {"49465800", "Infineon", "IFX"}, {"494E5443", "Intel", "INTC"}, {"4C454E00", "Lenovo", "LEN"}, + {"4D534654", "Microsoft", "MSFT"}, {"4E534D20", "National Semiconductor", "NSM"}, {"4E545A00", "Nationz", "NTZ"}, {"4E544300", "Nuvoton Technology", "NTC"}, {"51434F4D", "Qualcomm", "QCOM"}, + {"534D534E", "Samsung", "SECE"}, + {"53454345", "SecEdge", "SecEdge"}, + {"534E5300", "Sinosun", "SNS"}, {"534D5343", "SMSC", "SMSC"}, {"53544D20", "ST Microelectronics", "STM"}, - {"534D534E", "Samsung", "SMSN"}, - {"534E5300", "Sinosun", "SNS"}, {"54584E00", "Texas Instruments", "TXN"}, {"57454300", "Winbond", "WEC"}, - {"524F4343", "Fuzhouk Rockchip", "ROCC"}, + {"5345414C", "Wisekey", "SEAL"}, {"FFFFF1D0", "FIDO Alliance Conformance Testing", "FIDO"}, } @@ -372,3 +369,96 @@ func isValidTPMManufacturer(id string) bool { return false } + +func tpmParseAIKAttCA(x5c *x509.Certificate, x5cis []*x509.Certificate) (err *Error) { + if err = tpmParseSANExtension(x5c); err != nil { + return err + } + + if err = tpmRemoveEKU(x5c); err != nil { + return err + } + + for _, parent := range x5cis { + if err = tpmRemoveEKU(parent); err != nil { + return err + } + } + + return nil +} + +func tpmParseSANExtension(attestation *x509.Certificate) (protoErr *Error) { + var ( + manufacturer, model, version string + err error + ) + + for _, ext := range attestation.Extensions { + if ext.Id.Equal(oidExtensionSubjectAltName) { + if manufacturer, model, version, err = parseSANExtension(ext.Value); err != nil { + return ErrInvalidAttestation.WithDetails("Authenticator with invalid Authenticator Identity Key SAN data encountered during attestation validation.").WithInfo(fmt.Sprintf("Error occurred parsing SAN extension: %s", err.Error())).WithError(err) + } + } + } + + if manufacturer == "" || model == "" || version == "" { + return ErrAttestationFormat.WithDetails("Invalid SAN data in AIK certificate.") + } + + var unhandled []asn1.ObjectIdentifier + + for _, uce := range attestation.UnhandledCriticalExtensions { + if uce.Equal(oidExtensionSubjectAltName) { + continue + } + + unhandled = append(unhandled, uce) + } + + attestation.UnhandledCriticalExtensions = unhandled + + return nil +} + +var ( + oidExtensionSubjectAltName = []int{2, 5, 29, 17} + oidExtensionExtendedKeyUsage = []int{2, 5, 29, 37} + oidExtensionBasicConstraints = []int{2, 5, 29, 19} + oidKpPrivacyCA = []int{1, 3, 6, 1, 4, 1, 311, 21, 36} +) + +type tpmBasicConstraints struct { + IsCA bool `asn1:"optional"` + MaxPathLen int `asn1:"optional,default:-1"` +} + +// Remove extension key usage to avoid ExtKeyUsage check failure. +func tpmRemoveEKU(x5c *x509.Certificate) *Error { + var ( + unknown []asn1.ObjectIdentifier + hasAiK bool + ) + + for _, eku := range x5c.UnknownExtKeyUsage { + if eku.Equal(tcgKpAIKCertificate) { + hasAiK = true + + continue + } + + if eku.Equal(oidKpPrivacyCA) { + continue + } + + unknown = append(unknown, eku) + } + + if !hasAiK { + return ErrAttestationFormat.WithDetails("Attestation Identity Key certificate missing required Extended Key Usage.") + } + + x5c.UnknownExtKeyUsage = unknown + + return nil +} diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/attestation_u2f.go b/vendor/github.com/go-webauthn/webauthn/protocol/attestation_u2f.go index e203f072e35cfac4de009c49fbf86e341749a0e4..3b858f5fe85f1bbb203a38268301eaf4e4892714 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/attestation_u2f.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/attestation_u2f.go @@ -11,14 +11,12 @@ import ( "github.com/go-webauthn/webauthn/protocol/webauthncose" ) -var u2fAttestationKey = "fido-u2f" - func init() { - RegisterAttestationFormat(u2fAttestationKey, verifyU2FFormat) + RegisterAttestationFormat(AttestationFormatFIDOUniversalSecondFactor, verifyU2FFormat) } // verifyU2FFormat - Follows verification steps set out by https://www.w3.org/TR/webauthn/#fido-u2f-attestation -func verifyU2FFormat(att AttestationObject, clientDataHash []byte) (string, []interface{}, error) { +func verifyU2FFormat(att AttestationObject, clientDataHash []byte, _ metadata.Provider) (string, []any, error) { if !bytes.Equal(att.AuthData.AttData.AAGUID, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) { return "", nil, ErrUnsupportedAlgorithm.WithDetails("U2F attestation format AAGUID not set to 0x00") } @@ -42,7 +40,7 @@ func verifyU2FFormat(att AttestationObject, clientDataHash []byte) (string, []in // } // Check for "x5c" which is a single element array containing the attestation certificate in X.509 format. - x5c, present := att.AttStatement["x5c"].([]interface{}) + x5c, present := att.AttStatement[stmtX5C].([]any) if !present { return "", nil, ErrAttestationFormat.WithDetails("Missing properly formatted x5c data") } @@ -50,7 +48,7 @@ func verifyU2FFormat(att AttestationObject, clientDataHash []byte) (string, []in // Check for "sig" which is The attestation signature. The signature was calculated over the (raw) U2F // registration response message https://www.w3.org/TR/webauthn/#biblio-fido-u2f-message-formats] // received by the client from the authenticator. - signature, present := att.AttStatement["sig"].([]byte) + signature, present := att.AttStatement[stmtSignature].([]byte) if !present { return "", nil, ErrAttestationFormat.WithDetails("Missing sig data") } @@ -78,7 +76,7 @@ func verifyU2FFormat(att AttestationObject, clientDataHash []byte) (string, []in attCert, err := x509.ParseCertificate(asn1Bytes) if err != nil { - return "", nil, ErrAttestationFormat.WithDetails("Error parsing certificate from ASN.1 data into certificate") + return "", nil, ErrAttestationFormat.WithDetails("Error parsing certificate from ASN.1 data into certificate").WithError(err) } // Step 2.3 diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/authenticator.go b/vendor/github.com/go-webauthn/webauthn/protocol/authenticator.go index 8424fe53a2c7da6942a8fd6df26a8ed13a2c0797..4cd636a2f854fd7345f3b976380669fbb8b0305d 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/authenticator.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/authenticator.go @@ -57,6 +57,36 @@ type AttestedCredentialData struct { CredentialPublicKey []byte `json:"public_key"` } +// CredentialMediationRequirement represents mediation requirements for clients. When making a request via get(options) +// or create(options), developers can set a case-by-case requirement for user mediation by choosing the appropriate +// CredentialMediationRequirement enum value. +// +// See https://www.w3.org/TR/credential-management-1/#mediation-requirements +type CredentialMediationRequirement string + +const ( + // MediationSilent indicates user mediation is suppressed for the given operation. If the operation can be performed + // without user involvement, wonderful. If user involvement is necessary, then the operation will return null rather + // than involving the user. + MediationSilent CredentialMediationRequirement = "silent" + + // MediationOptional indicates if credentials can be handed over for a given operation without user mediation, they + // will be. If user mediation is required, then the user agent will involve the user in the decision. + MediationOptional CredentialMediationRequirement = "optional" + + // MediationConditional indicates for get(), discovered credentials are presented to the user in a non-modal dialog + // along with an indication of the origin which is requesting credentials. If the user makes a gesture outside of + // the dialog, the dialog closes without resolving or rejecting the Promise returned by the get() method and without + // causing a user-visible error condition. If the user makes a gesture that selects a credential, that credential is + // returned to the caller. The prevent silent access flag is treated as being true regardless of its actual value: + // the conditional behavior always involves user mediation of some sort if applicable credentials are discovered. + MediationConditional CredentialMediationRequirement = "conditional" + + // MediationRequired indicates the user agent will not hand over credentials without user mediation, even if the + // prevent silent access flag is unset for an origin. + MediationRequired CredentialMediationRequirement = "required" +) + // AuthenticatorAttachment represents the IDL enum of the same name, and is used as part of the Authenticator Selection // Criteria. // @@ -135,6 +165,11 @@ const ( // BLE indicates the respective authenticator can be contacted over Bluetooth Smart (Bluetooth Low Energy / BLE). BLE AuthenticatorTransport = "ble" + // SmartCard indicates the respective authenticator can be contacted over ISO/IEC 7816 smart card with contacts. + // + // WebAuthn Level 3. + SmartCard AuthenticatorTransport = "smart-card" + // Hybrid indicates the respective authenticator can be contacted using a combination of (often separate) // data-transport and proximity mechanisms. This supports, for example, authentication on a desktop computer using // a smartphone. @@ -314,7 +349,7 @@ func (a *AuthenticatorData) unmarshalAttestedData(rawAuthData []byte) (err error a.AttData.CredentialPublicKey, err = unmarshalCredentialPublicKey(rawAuthData[55+idLength:]) if err != nil { - return ErrBadRequest.WithDetails(fmt.Sprintf("Could not unmarshal Credential Public Key: %v", err)) + return ErrBadRequest.WithDetails(fmt.Sprintf("Could not unmarshal Credential Public Key: %v", err)).WithError(err) } return nil @@ -322,7 +357,7 @@ func (a *AuthenticatorData) unmarshalAttestedData(rawAuthData []byte) (err error // Unmarshall the credential's Public Key into CBOR encoding. func unmarshalCredentialPublicKey(keyBytes []byte) (rawBytes []byte, err error) { - var m interface{} + var m any if err = webauthncbor.Unmarshal(keyBytes, &m); err != nil { return nil, err @@ -348,11 +383,6 @@ func ResidentKeyNotRequired() *bool { return &required } -// Deprecated: ResidentKeyUnrequired is an alias for ResidentKeyNotRequired and will be completely removed in the future. -func ResidentKeyUnrequired() *bool { - return ResidentKeyNotRequired() -} - // Verify on AuthenticatorData handles Steps 9 through 12 for Registration // and Steps 11 through 14 for Assertion. func (a *AuthenticatorData) Verify(rpIdHash []byte, appIDHash []byte, userVerificationRequired bool) error { diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/base64.go b/vendor/github.com/go-webauthn/webauthn/protocol/base64.go index 8e2910942d8a30391768741dfff29d6cabe2afb0..86f36b6ac4b29d811b7b0ac05391a7496b4b2b1c 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/base64.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/base64.go @@ -22,9 +22,8 @@ func (e *URLEncodedBase64) UnmarshalJSON(data []byte) error { return nil } - // TODO: Investigate this line. It is commented as trimming the leading spaces but appears to trim the leading and trailing double quotes instead. - // Trim the leading spaces. - data = bytes.Trim(data, "\"") + // Trim the leading and trailing quotes from raw JSON data (the whole value part) + data = bytes.Trim(data, `"`) // Trim the trailing equal characters. data = bytes.TrimRight(data, "=") diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/client.go b/vendor/github.com/go-webauthn/webauthn/protocol/client.go index c98577aab800cd6f32efa89fbc514e2706fe6674..e5c21672e435b72505fc943217ac59d9bda51bf4 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/client.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/client.go @@ -16,10 +16,12 @@ type CollectedClientData struct { // Type the string "webauthn.create" when creating new credentials, // and "webauthn.get" when getting an assertion from an existing credential. The // purpose of this member is to prevent certain types of signature confusion attacks - //(where an attacker substitutes one legitimate signature for another). + // (where an attacker substitutes one legitimate signature for another). Type CeremonyType `json:"type"` Challenge string `json:"challenge"` Origin string `json:"origin"` + TopOrigin string `json:"topOrigin,omitempty"` + CrossOrigin bool `json:"crossOrigin,omitempty"` TokenBinding *TokenBinding `json:"tokenBinding,omitempty"` // Chromium (Chrome) returns a hint sometimes about how to handle clientDataJSON in a safe manner. @@ -41,13 +43,15 @@ type TokenBinding struct { type TokenBindingStatus string const ( - // Indicates token binding was used when communicating with the + // Present indicates token binding was used when communicating with the // Relying Party. In this case, the id member MUST be present. Present TokenBindingStatus = "present" - // Indicates token binding was used when communicating with the + + // Supported indicates token binding was used when communicating with the // negotiated when communicating with the Relying Party. Supported TokenBindingStatus = "supported" - // Indicates token binding not supported + + // NotSupported indicates token binding not supported // when communicating with the Relying Party. NotSupported TokenBindingStatus = "not-supported" ) @@ -77,7 +81,10 @@ func FullyQualifiedOrigin(rawOrigin string) (fqOrigin string, err error) { // new credential and steps 7 through 10 of verifying an authentication assertion // See https://www.w3.org/TR/webauthn/#registering-a-new-credential // and https://www.w3.org/TR/webauthn/#verifying-assertion -func (c *CollectedClientData) Verify(storedChallenge string, ceremony CeremonyType, rpOrigins []string) error { +// +// Note: the rpTopOriginsVerify parameter does not accept the TopOriginVerificationMode value of +// TopOriginDefaultVerificationMode as it's expected this value is updated by the config validation process. +func (c *CollectedClientData) Verify(storedChallenge string, ceremony CeremonyType, rpOrigins, rpTopOrigins []string, rpTopOriginsVerify TopOriginVerificationMode) (err error) { // Registration Step 3. Verify that the value of C.type is webauthn.create. // Assertion Step 7. Verify that the value of C.type is the string webauthn.get. @@ -101,9 +108,10 @@ func (c *CollectedClientData) Verify(storedChallenge string, ceremony CeremonyTy // Registration Step 5 & Assertion Step 9. Verify that the value of C.origin matches // the Relying Party's origin. - fqOrigin, err := FullyQualifiedOrigin(c.Origin) - if err != nil { - return ErrParsingData.WithDetails("Error decoding clientData origin as URL") + var fqOrigin string + + if fqOrigin, err = FullyQualifiedOrigin(c.Origin); err != nil { + return ErrParsingData.WithDetails("Error decoding clientData origin as URL").WithError(err) } found := false @@ -121,6 +129,54 @@ func (c *CollectedClientData) Verify(storedChallenge string, ceremony CeremonyTy WithInfo(fmt.Sprintf("Expected Values: %s, Received: %s", rpOrigins, fqOrigin)) } + if rpTopOriginsVerify != TopOriginIgnoreVerificationMode { + switch len(c.TopOrigin) { + case 0: + break + default: + if !c.CrossOrigin { + return ErrVerification. + WithDetails("Error validating topOrigin"). + WithInfo("The topOrigin can't have values unless crossOrigin is true.") + } + + var ( + fqTopOrigin string + possibleTopOrigins []string + ) + + if fqTopOrigin, err = FullyQualifiedOrigin(c.TopOrigin); err != nil { + return ErrParsingData.WithDetails("Error decoding clientData topOrigin as URL").WithError(err) + } + + switch rpTopOriginsVerify { + case TopOriginExplicitVerificationMode: + possibleTopOrigins = rpTopOrigins + case TopOriginAutoVerificationMode: + possibleTopOrigins = append(rpTopOrigins, rpOrigins...) + case TopOriginImplicitVerificationMode: + possibleTopOrigins = rpOrigins + default: + return ErrNotImplemented.WithDetails("Error handling unknown Top Origin verification mode") + } + + found = false + + for _, origin := range possibleTopOrigins { + if strings.EqualFold(fqTopOrigin, origin) { + found = true + break + } + } + + if !found { + return ErrVerification. + WithDetails("Error validating top origin"). + WithInfo(fmt.Sprintf("Expected Values: %s, Received: %s", possibleTopOrigins, fqTopOrigin)) + } + } + } + // Registration Step 6 and Assertion Step 10. Verify that the value of C.tokenBinding.status // matches the state of Token Binding for the TLS connection over which the assertion was // obtained. If Token Binding was used on that TLS connection, also verify that C.tokenBinding.id @@ -140,3 +196,28 @@ func (c *CollectedClientData) Verify(storedChallenge string, ceremony CeremonyTy return nil } + +type TopOriginVerificationMode int + +const ( + // TopOriginDefaultVerificationMode represents the default verification mode for the Top Origin. At this time this + // mode is the same as TopOriginIgnoreVerificationMode until such a time as the specification becomes stable. This + // value is intended as a fallback value and implementers should very intentionally pick another option if they want + // stability. + TopOriginDefaultVerificationMode TopOriginVerificationMode = iota + + // TopOriginIgnoreVerificationMode ignores verification entirely. + TopOriginIgnoreVerificationMode + + // TopOriginAutoVerificationMode represents the automatic verification mode for the Top Origin. In this mode the + // If the Top Origins parameter has values it checks against this, otherwise it checks against the Origins parameter. + TopOriginAutoVerificationMode + + // TopOriginImplicitVerificationMode represents the implicit verification mode for the Top Origin. In this mode the + // Top Origin is verified against the allowed Origins values. + TopOriginImplicitVerificationMode + + // TopOriginExplicitVerificationMode represents the explicit verification mode for the Top Origin. In this mode the + // Top Origin is verified against the allowed Top Origins values. + TopOriginExplicitVerificationMode +) diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/const.go b/vendor/github.com/go-webauthn/webauthn/protocol/const.go new file mode 100644 index 0000000000000000000000000000000000000000..a1560f2595c3c08ceda30948e7a5bbd325558c39 --- /dev/null +++ b/vendor/github.com/go-webauthn/webauthn/protocol/const.go @@ -0,0 +1,11 @@ +package protocol + +const ( + stmtX5C = "x5c" + stmtSignature = "sig" + stmtAlgorithm = "alg" + stmtVersion = "ver" + stmtECDAAKID = "ecdaaKeyId" + stmtCertInfo = "certInfo" + stmtPubArea = "pubArea" +) diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/credential.go b/vendor/github.com/go-webauthn/webauthn/protocol/credential.go index bb9782b0f2dbad2fdfc95fbfdcb56610d90d3f7f..7b18a1d2a546f1c403d1a73738e78d1b3b7df211 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/credential.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/credential.go @@ -5,6 +5,8 @@ import ( "encoding/base64" "io" "net/http" + + "github.com/go-webauthn/webauthn/metadata" ) // Credential is the basic credential type from the Credential Management specification that is inherited by WebAuthn's @@ -31,6 +33,7 @@ type ParsedCredential struct { type PublicKeyCredential struct { Credential + RawID URLEncodedBase64 `json:"rawId"` ClientExtensionResults AuthenticationExtensionsClientOutputs `json:"clientExtensionResults,omitempty"` AuthenticatorAttachment string `json:"authenticatorAttachment,omitempty"` @@ -38,6 +41,7 @@ type PublicKeyCredential struct { type ParsedPublicKeyCredential struct { ParsedCredential + RawID []byte `json:"rawId"` ClientExtensionResults AuthenticationExtensionsClientOutputs `json:"clientExtensionResults,omitempty"` AuthenticatorAttachment AuthenticatorAttachment `json:"authenticatorAttachment,omitempty"` @@ -45,17 +49,13 @@ type ParsedPublicKeyCredential struct { type CredentialCreationResponse struct { PublicKeyCredential - AttestationResponse AuthenticatorAttestationResponse `json:"response"` - // Deprecated: Transports is deprecated due to upstream changes to the API. - // Use the Transports field of AuthenticatorAttestationResponse - // instead. Transports is kept for backward compatibility, and should not - // be used by new clients. - Transports []string `json:"transports,omitempty"` + AttestationResponse AuthenticatorAttestationResponse `json:"response"` } type ParsedCredentialCreationData struct { ParsedPublicKeyCredential + Response ParsedAttestationResponse Raw CredentialCreationResponse } @@ -79,7 +79,19 @@ func ParseCredentialCreationResponseBody(body io.Reader) (pcc *ParsedCredentialC var ccr CredentialCreationResponse if err = decodeBody(body, &ccr); err != nil { - return nil, ErrBadRequest.WithDetails("Parse error for Registration").WithInfo(err.Error()) + return nil, ErrBadRequest.WithDetails("Parse error for Registration").WithInfo(err.Error()).WithError(err) + } + + return ccr.Parse() +} + +// ParseCredentialCreationResponseBytes is an alternative version of ParseCredentialCreationResponseBody that just takes +// a byte slice. +func ParseCredentialCreationResponseBytes(data []byte) (pcc *ParsedCredentialCreationData, err error) { + var ccr CredentialCreationResponse + + if err = decodeBytes(data, &ccr); err != nil { + return nil, ErrBadRequest.WithDetails("Parse error for Registration").WithInfo(err.Error()).WithError(err) } return ccr.Parse() @@ -103,7 +115,7 @@ func (ccr CredentialCreationResponse) Parse() (pcc *ParsedCredentialCreationData return nil, ErrBadRequest.WithDetails("Parse error for Registration").WithInfo("Missing type") } - if ccr.PublicKeyCredential.Credential.Type != "public-key" { + if ccr.PublicKeyCredential.Credential.Type != string(PublicKeyCredentialType) { return nil, ErrBadRequest.WithDetails("Parse error for Registration").WithInfo("Type not public-key") } @@ -112,13 +124,6 @@ func (ccr CredentialCreationResponse) Parse() (pcc *ParsedCredentialCreationData return nil, ErrParsingData.WithDetails("Error parsing attestation response") } - // TODO: Remove this as it's a backwards compatibility layer. - if len(response.Transports) == 0 && len(ccr.Transports) != 0 { - for _, t := range ccr.Transports { - response.Transports = append(response.Transports, AuthenticatorTransport(t)) - } - } - var attachment AuthenticatorAttachment switch ccr.AuthenticatorAttachment { @@ -140,15 +145,15 @@ func (ccr CredentialCreationResponse) Parse() (pcc *ParsedCredentialCreationData // Verify the Client and Attestation data. // // Specification: §7.1. Registering a New Credential (https://www.w3.org/TR/webauthn/#sctn-registering-a-new-credential) -func (pcc *ParsedCredentialCreationData) Verify(storedChallenge string, verifyUser bool, relyingPartyID string, relyingPartyOrigins []string) error { +func (pcc *ParsedCredentialCreationData) Verify(storedChallenge string, verifyUser bool, relyingPartyID string, rpOrigins, rpTopOrigins []string, rpTopOriginsVerify TopOriginVerificationMode, mds metadata.Provider) (clientDataHash []byte, err error) { // Handles steps 3 through 6 - Verifying the Client Data against the Relying Party's stored data - verifyError := pcc.Response.CollectedClientData.Verify(storedChallenge, CreateCeremony, relyingPartyOrigins) - if verifyError != nil { - return verifyError + if err = pcc.Response.CollectedClientData.Verify(storedChallenge, CreateCeremony, rpOrigins, rpTopOrigins, rpTopOriginsVerify); err != nil { + return nil, err } // Step 7. Compute the hash of response.clientDataJSON using SHA-256. - clientDataHash := sha256.Sum256(pcc.Raw.AttestationResponse.ClientDataJSON) + sum := sha256.Sum256(pcc.Raw.AttestationResponse.ClientDataJSON) + clientDataHash = sum[:] // Step 8. Perform CBOR decoding on the attestationObject field of the AuthenticatorAttestationResponse // structure to obtain the attestation statement format fmt, the authenticator data authData, and the @@ -156,9 +161,8 @@ func (pcc *ParsedCredentialCreationData) Verify(storedChallenge string, verifyUs // We do the above step while parsing and decoding the CredentialCreationResponse // Handle steps 9 through 14 - This verifies the attestation object. - verifyError = pcc.Response.AttestationObject.Verify(relyingPartyID, clientDataHash[:], verifyUser) - if verifyError != nil { - return verifyError + if err = pcc.Response.AttestationObject.Verify(relyingPartyID, clientDataHash, verifyUser, mds); err != nil { + return clientDataHash, err } // Step 15. If validation is successful, obtain a list of acceptable trust anchors (attestation root @@ -197,7 +201,7 @@ func (pcc *ParsedCredentialCreationData) Verify(storedChallenge string, verifyUs // TODO: Not implemented for the reasons mentioned under Step 16 - return nil + return clientDataHash, nil } // GetAppID takes a AuthenticationExtensions object or nil. It then performs the following checks in order: diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/decoder.go b/vendor/github.com/go-webauthn/webauthn/protocol/decoder.go index 92e8a81c89fe5716bcaf508bb082df8b812354d1..bd763168825204e750fa5ce979a7662790a1738d 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/decoder.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/decoder.go @@ -1,6 +1,7 @@ package protocol import ( + "bytes" "encoding/json" "errors" "io" @@ -21,3 +22,19 @@ func decodeBody(body io.Reader, v any) (err error) { return nil } + +func decodeBytes(data []byte, v any) (err error) { + decoder := json.NewDecoder(bytes.NewReader(data)) + + if err = decoder.Decode(v); err != nil { + return err + } + + _, err = decoder.Token() + + if !errors.Is(err, io.EOF) { + return errors.New("The body contains trailing data") + } + + return nil +} diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/entities.go b/vendor/github.com/go-webauthn/webauthn/protocol/entities.go index 1d2f6e8daf99d51cd7a6f34c7b1fd0eaf8c117ca..b0ba2addeda8dd541171f7d0ef787445ea0b19ab 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/entities.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/entities.go @@ -14,16 +14,6 @@ type CredentialEntity struct { // intended only for display, i.e., aiding the user in determining the difference between user accounts with similar // displayNames. For example, "alexm", "alex.p.mueller@example.com" or "+14255551234". Name string `json:"name"` - - // A serialized URL which resolves to an image associated with the entity. For example, - // this could be a user’s avatar or a Relying Party's logo. This URL MUST be an a priori - // authenticated URL. Authenticators MUST accept and store a 128-byte minimum length for - // an icon member’s value. Authenticators MAY ignore an icon member’s value if its length - // is greater than 128 bytes. The URL’s scheme MAY be "data" to avoid fetches of the URL, - // at the cost of needing more storage. - // - // Deprecated: this has been removed from the specification recommendations. - Icon string `json:"icon,omitempty"` } // The RelyingPartyEntity represents the PublicKeyCredentialRpEntity IDL and is used to supply additional Relying Party @@ -32,6 +22,7 @@ type CredentialEntity struct { // Specification: §5.4.2. Relying Party Parameters for Credential Generation (https://www.w3.org/TR/webauthn/#dictionary-rp-credential-params) type RelyingPartyEntity struct { CredentialEntity + // A unique identifier for the Relying Party entity, which sets the RP ID. ID string `json:"id"` } @@ -51,5 +42,5 @@ type UserEntity struct { // authentication and authorization decisions MUST be made on the basis of this id // member, not the displayName nor name members. See Section 6.1 of // [RFC8266](https://www.w3.org/TR/webauthn/#biblio-rfc8266). - ID interface{} `json:"id"` + ID any `json:"id"` } diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/errors.go b/vendor/github.com/go-webauthn/webauthn/protocol/errors.go index 6d134d63ec537831f259ff0ae0146933d8fbc5d4..d09b80ebd1b70e8c3d19c1af6726bf02356825b6 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/errors.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/errors.go @@ -9,6 +9,38 @@ type Error struct { // Information to help debug the error. DevInfo string `json:"debug"` + + // Inner error. + Err error `json:"-"` +} + +func (e *Error) Error() string { + return e.Details +} + +func (e *Error) Unwrap() error { + return e.Err +} + +func (e *Error) WithDetails(details string) *Error { + err := *e + err.Details = details + + return &err +} + +func (e *Error) WithInfo(info string) *Error { + err := *e + err.DevInfo = info + + return &err +} + +func (e *Error) WithError(err error) *Error { + errCopy := *e + errCopy.Err = err + + return &errCopy } var ( @@ -40,6 +72,10 @@ var ( Type: "invalid_attestation", Details: "Invalid attestation data", } + ErrMetadata = &Error{ + Type: "invalid_metadata", + Details: "", + } ErrAttestationFormat = &Error{ Type: "invalid_attestation", Details: "Invalid attestation format", @@ -69,21 +105,3 @@ var ( Details: "This field is not yet supported by this library", } ) - -func (e *Error) Error() string { - return e.Details -} - -func (e *Error) WithDetails(details string) *Error { - err := *e - err.Details = details - - return &err -} - -func (e *Error) WithInfo(info string) *Error { - err := *e - err.DevInfo = info - - return &err -} diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/extensions.go b/vendor/github.com/go-webauthn/webauthn/protocol/extensions.go index f925eb24f0d380eb8cf05acd69355659cebbc046..e226f7ca2da87372710ca83c05a4d252f3757d03 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/extensions.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/extensions.go @@ -5,7 +5,7 @@ package protocol // For a list of commonly supported extensions, see §10. Defined Extensions // (https://www.w3.org/TR/webauthn/#sctn-defined-extensions). -type AuthenticationExtensionsClientOutputs map[string]interface{} +type AuthenticationExtensionsClientOutputs map[string]any const ( ExtensionAppID = "appid" diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/metadata.go b/vendor/github.com/go-webauthn/webauthn/protocol/metadata.go new file mode 100644 index 0000000000000000000000000000000000000000..01af76ae44f74d31dfc9bd8f57bfc8f55706f918 --- /dev/null +++ b/vendor/github.com/go-webauthn/webauthn/protocol/metadata.go @@ -0,0 +1,126 @@ +package protocol + +import ( + "context" + "crypto/x509" + "fmt" + + "github.com/google/uuid" + + "github.com/go-webauthn/webauthn/metadata" +) + +func ValidateMetadata(ctx context.Context, mds metadata.Provider, aaguid uuid.UUID, attestationType string, x5cs []any) (protoErr *Error) { + if mds == nil { + return nil + } + + var ( + entry *metadata.Entry + err error + ) + + if entry, err = mds.GetEntry(ctx, aaguid); err != nil { + return ErrMetadata.WithInfo(fmt.Sprintf("Failed to validate authenticator metadata for Authenticator Attestation GUID '%s'. Error occurred retreiving the metadata entry: %+v", aaguid, err)) + } + + if entry == nil { + if aaguid == uuid.Nil && mds.GetValidateEntryPermitZeroAAGUID(ctx) { + return nil + } + + if mds.GetValidateEntry(ctx) { + return ErrMetadata.WithInfo(fmt.Sprintf("Failed to validate authenticator metadata for Authenticator Attestation GUID '%s'. The authenticator has no registered metadata.", aaguid)) + } + + return nil + } + + if mds.GetValidateAttestationTypes(ctx) && attestationType != "" { + found := false + + for _, atype := range entry.MetadataStatement.AttestationTypes { + if string(atype) == attestationType { + found = true + + break + } + } + + if !found { + return ErrMetadata.WithInfo(fmt.Sprintf("Failed to validate authenticator metadata for Authenticator Attestation GUID '%s'. The attestation type '%s' is not known to be used by this authenticator.", aaguid.String(), attestationType)) + } + } + + if mds.GetValidateStatus(ctx) { + if err = mds.ValidateStatusReports(ctx, entry.StatusReports); err != nil { + return ErrMetadata.WithInfo(fmt.Sprintf("Failed to validate authenticator metadata for Authenticator Attestation GUID '%s'. Error occurred validating the authenticator status: %+v", aaguid, err)) + } + } + + if mds.GetValidateTrustAnchor(ctx) { + if len(x5cs) == 0 { + return nil + } + + var ( + x5c, parsed *x509.Certificate + x5cis []*x509.Certificate + raw []byte + ok bool + ) + + for i, x5cAny := range x5cs { + if raw, ok = x5cAny.([]byte); !ok { + return ErrMetadata.WithDetails(fmt.Sprintf("Failed to parse attestation certificate from x5c during attestation validation for Authenticator Attestation GUID '%s'.", aaguid)).WithInfo(fmt.Sprintf("The %s certificate in the attestation was type '%T' but '[]byte' was expected", loopOrdinalNumber(i), x5cAny)) + } + + if parsed, err = x509.ParseCertificate(raw); err != nil { + return ErrMetadata.WithDetails(fmt.Sprintf("Failed to parse attestation certificate from x5c during attestation validation for Authenticator Attestation GUID '%s'.", aaguid)).WithInfo(fmt.Sprintf("Error returned from x509.ParseCertificate: %+v", err)).WithError(err) + } + + if x5c == nil { + x5c = parsed + } else { + x5cis = append(x5cis, parsed) + } + } + + if attestationType == string(metadata.AttCA) { + if protoErr = tpmParseAIKAttCA(x5c, x5cis); protoErr != nil { + return ErrMetadata.WithDetails(protoErr.Details).WithInfo(protoErr.DevInfo).WithError(protoErr) + } + } + + if x5c != nil && x5c.Subject.CommonName != x5c.Issuer.CommonName { + if !entry.MetadataStatement.AttestationTypes.HasBasicFull() { + return ErrMetadata.WithDetails(fmt.Sprintf("Failed to validate attestation statement signature during attestation validation for Authenticator Attestation GUID '%s'. Attestation was provided in the full format but the authenticator doesn't support the full attestation format.", aaguid)) + } + + if _, err = x5c.Verify(entry.MetadataStatement.Verifier(x5cis)); err != nil { + return ErrMetadata.WithDetails(fmt.Sprintf("Failed to validate attestation statement signature during attestation validation for Authenticator Attestation GUID '%s'. The attestation certificate could not be verified due to an error validating the trust chain agaisnt the Metadata Service.", aaguid)).WithError(err) + } + } + } + + return nil +} + +func loopOrdinalNumber(n int) string { + n++ + + if n > 9 && n < 20 { + return fmt.Sprintf("%dth", n) + } + + switch n % 10 { + case 1: + return fmt.Sprintf("%dst", n) + case 2: + return fmt.Sprintf("%dnd", n) + case 3: + return fmt.Sprintf("%drd", n) + default: + return fmt.Sprintf("%dth", n) + } +} diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/options.go b/vendor/github.com/go-webauthn/webauthn/protocol/options.go index 80a9e552265475bae391fbbfd19d809def240a9b..a070e7cc1cdf9a3653ce3c01da97011c10ea5441 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/options.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/options.go @@ -5,11 +5,13 @@ import ( ) type CredentialCreation struct { - Response PublicKeyCredentialCreationOptions `json:"publicKey"` + Response PublicKeyCredentialCreationOptions `json:"publicKey"` + Mediation CredentialMediationRequirement `json:"mediation,omitempty"` } type CredentialAssertion struct { - Response PublicKeyCredentialRequestOptions `json:"publicKey"` + Response PublicKeyCredentialRequestOptions `json:"publicKey"` + Mediation CredentialMediationRequirement `json:"mediation,omitempty"` } // PublicKeyCredentialCreationOptions represents the IDL of the same name. @@ -17,26 +19,27 @@ type CredentialAssertion struct { // In order to create a Credential via create(), the caller specifies a few parameters in a // PublicKeyCredentialCreationOptions object. // -// TODO: There is one field missing from this for WebAuthn Level 3. A string slice named 'attestationFormats'. +// WebAuthn Level 3: hints,attestationFormats. // // Specification: §5.4. Options for Credential Creation (https://www.w3.org/TR/webauthn/#dictionary-makecredentialoptions) type PublicKeyCredentialCreationOptions struct { - RelyingParty RelyingPartyEntity `json:"rp"` - User UserEntity `json:"user"` - Challenge URLEncodedBase64 `json:"challenge"` - Parameters []CredentialParameter `json:"pubKeyCredParams,omitempty"` - Timeout int `json:"timeout,omitempty"` - CredentialExcludeList []CredentialDescriptor `json:"excludeCredentials,omitempty"` - AuthenticatorSelection AuthenticatorSelection `json:"authenticatorSelection,omitempty"` - Attestation ConveyancePreference `json:"attestation,omitempty"` - Extensions AuthenticationExtensions `json:"extensions,omitempty"` + RelyingParty RelyingPartyEntity `json:"rp"` + User UserEntity `json:"user"` + Challenge URLEncodedBase64 `json:"challenge"` + Parameters []CredentialParameter `json:"pubKeyCredParams,omitempty"` + Timeout int `json:"timeout,omitempty"` + CredentialExcludeList []CredentialDescriptor `json:"excludeCredentials,omitempty"` + AuthenticatorSelection AuthenticatorSelection `json:"authenticatorSelection,omitempty"` + Hints []PublicKeyCredentialHints `json:"hints,omitempty"` + Attestation ConveyancePreference `json:"attestation,omitempty"` + AttestationFormats []AttestationFormat `json:"attestationFormats,omitempty"` + Extensions AuthenticationExtensions `json:"extensions,omitempty"` } // The PublicKeyCredentialRequestOptions dictionary supplies get() with the data it needs to generate an assertion. // Its challenge member MUST be present, while its other members are OPTIONAL. // -// TODO: There are two fields missing from this for WebAuthn Level 3. A string type named 'attestation', and a string -// slice named 'attestationFormats'. +// WebAuthn Level 3: hints. // // Specification: §5.5. Options for Assertion Generation (https://www.w3.org/TR/webauthn/#dictionary-assertion-options) type PublicKeyCredentialRequestOptions struct { @@ -45,6 +48,7 @@ type PublicKeyCredentialRequestOptions struct { RelyingPartyID string `json:"rpId,omitempty"` AllowedCredentials []CredentialDescriptor `json:"allowCredentials,omitempty"` UserVerification UserVerificationRequirement `json:"userVerification,omitempty"` + Hints []PublicKeyCredentialHints `json:"hints,omitempty"` Extensions AuthenticationExtensions `json:"extensions,omitempty"` } @@ -98,7 +102,7 @@ const ( // parameters requesting additional processing by the client and authenticator. // // Specification: §5.7.1. Authentication Extensions Client Inputs (https://www.w3.org/TR/webauthn/#iface-authentication-extensions-client-inputs) -type AuthenticationExtensions map[string]interface{} +type AuthenticationExtensions map[string]any // AuthenticatorSelection represents the AuthenticatorSelectionCriteria IDL. // @@ -183,6 +187,72 @@ const ( PreferEnterpriseAttestation ConveyancePreference = "enterprise" ) +// AttestationFormat is an internal representation of the relevant inputs for registration. +// +// Specification: §5.4 Options for Credential Creation (https://w3c.github.io/webauthn/#dom-publickeycredentialcreationoptions-attestationformats) +// Registry: https://www.iana.org/assignments/webauthn/webauthn.xhtml +type AttestationFormat string + +const ( + // AttestationFormatPacked is the "packed" attestation statement format is a WebAuthn-optimized format for + // attestation. It uses a very compact but still extensible encoding method. This format is implementable by + // authenticators with limited resources (e.g., secure elements). + AttestationFormatPacked AttestationFormat = "packed" + + // AttestationFormatTPM is the TPM attestation statement format returns an attestation statement in the same format + // as the packed attestation statement format, although the rawData and signature fields are computed differently. + AttestationFormatTPM AttestationFormat = "tpm" + + // AttestationFormatAndroidKey is the attestation statement format for platform authenticators on versions "N", and + // later, which may provide this proprietary "hardware attestation" statement. + AttestationFormatAndroidKey AttestationFormat = "android-key" + + // AttestationFormatAndroidSafetyNet is the attestation statement format that Android-based platform authenticators + // MAY produce an attestation statement based on the Android SafetyNet API. + AttestationFormatAndroidSafetyNet AttestationFormat = "android-safetynet" + + // AttestationFormatFIDOUniversalSecondFactor is the attestation statement format that is used with FIDO U2F + // authenticators. + AttestationFormatFIDOUniversalSecondFactor AttestationFormat = "fido-u2f" + + // AttestationFormatApple is the attestation statement format that is used with Apple devices' platform + // authenticators. + AttestationFormatApple AttestationFormat = "apple" + + // AttestationFormatNone is the attestation statement format that is used to replace any authenticator-provided + // attestation statement when a WebAuthn Relying Party indicates it does not wish to receive attestation information. + AttestationFormatNone AttestationFormat = "none" +) + +type PublicKeyCredentialHints string + +const ( + // PublicKeyCredentialHintSecurityKey is a PublicKeyCredentialHint that indicates that the Relying Party believes + // that users will satisfy this request with a physical security key. For example, an enterprise Relying Party may + // set this hint if they have issued security keys to their employees and will only accept those authenticators for + // registration and authentication. + // + // For compatibility with older user agents, when this hint is used in PublicKeyCredentialCreationOptions, the + // authenticatorAttachment SHOULD be set to cross-platform. + PublicKeyCredentialHintSecurityKey PublicKeyCredentialHints = "security-key" + + // PublicKeyCredentialHintClientDevice is a PublicKeyCredentialHint that indicates that the Relying Party believes + // that users will satisfy this request with a platform authenticator attached to the client device. + // + // For compatibility with older user agents, when this hint is used in PublicKeyCredentialCreationOptions, the + // authenticatorAttachment SHOULD be set to platform. + PublicKeyCredentialHintClientDevice PublicKeyCredentialHints = "client-device" + + // PublicKeyCredentialHintHybrid is a PublicKeyCredentialHint that indicates that the Relying Party believes that + // users will satisfy this request with general-purpose authenticators such as smartphones. For example, a consumer + // Relying Party may believe that only a small fraction of their customers possesses dedicated security keys. This + // option also implies that the local platform authenticator should not be promoted in the UI. + // + // For compatibility with older user agents, when this hint is used in PublicKeyCredentialCreationOptions, the + // authenticatorAttachment SHOULD be set to cross-platform. + PublicKeyCredentialHintHybrid PublicKeyCredentialHints = "hybrid" +) + func (a *PublicKeyCredentialRequestOptions) GetAllowedCredentialIDs() [][]byte { var allowedCredentialIDs = make([][]byte, len(a.AllowedCredentials)) @@ -193,7 +263,7 @@ func (a *PublicKeyCredentialRequestOptions) GetAllowedCredentialIDs() [][]byte { return allowedCredentialIDs } -type Extensions interface{} +type Extensions any type ServerResponse struct { Status ServerResponseStatus `json:"status"` diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/webauthncbor/webauthncbor.go b/vendor/github.com/go-webauthn/webauthn/protocol/webauthncbor/webauthncbor.go index 2886d0f6674367c5e43519e22671119465cad76b..aff1ac182fedc9861b38a67d86bb0153a38015f9 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/webauthncbor/webauthncbor.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/webauthncbor/webauthncbor.go @@ -18,7 +18,7 @@ var ctap2CBOREncMode, _ = cbor.CTAP2EncOptions().EncMode() // Unmarshal parses the CBOR-encoded data into the value pointed to by v // following the CTAP2 canonical CBOR encoding form. // (https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#message-encoding) -func Unmarshal(data []byte, v interface{}) error { +func Unmarshal(data []byte, v any) error { // TODO (james-d-elliott): investigate the specific use case for Unmarshal vs UnmarshalFirst to determine the edge cases where this may be useful. _, err := ctap2CBORDecMode.UnmarshalFirst(data, v) @@ -28,6 +28,6 @@ func Unmarshal(data []byte, v interface{}) error { // Marshal encodes the value pointed to by v // following the CTAP2 canonical CBOR encoding form. // (https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#message-encoding) -func Marshal(v interface{}) ([]byte, error) { +func Marshal(v any) ([]byte, error) { return ctap2CBOREncMode.Marshal(v) } diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/webauthncose/ed25519.go b/vendor/github.com/go-webauthn/webauthn/protocol/webauthncose/ed25519.go index b3dc1f83450c8d5230fb31eca9a61d4842f2f23e..d84c73cbaef8b4fdde43fb996c45e4122e55a0dc 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/webauthncose/ed25519.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/webauthncose/ed25519.go @@ -1,5 +1,3 @@ -//go:build go1.13 - package webauthncose import ( diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/webauthncose/ed25519_go112.go b/vendor/github.com/go-webauthn/webauthn/protocol/webauthncose/ed25519_go112.go deleted file mode 100644 index 7dc8c5381b43d710d0e60b468475e60e161ebcf4..0000000000000000000000000000000000000000 --- a/vendor/github.com/go-webauthn/webauthn/protocol/webauthncose/ed25519_go112.go +++ /dev/null @@ -1,38 +0,0 @@ -//go:build !go1.13 - -package webauthncose - -import ( - "crypto/x509/pkix" - "encoding/asn1" - - "golang.org/x/crypto/ed25519" -) - -var oidSignatureEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112} - -type pkixPublicKey struct { - Algo pkix.AlgorithmIdentifier - BitString asn1.BitString -} - -// marshalEd25519PublicKey is a backport of the functionality introduced in -// Go v1.13. -// Ref: https://golang.org/doc/go1.13#crypto/ed25519 -// Ref: https://golang.org/doc/go1.13#crypto/x509 -func marshalEd25519PublicKey(pub ed25519.PublicKey) ([]byte, error) { - publicKeyBytes := pub - var publicKeyAlgorithm pkix.AlgorithmIdentifier - publicKeyAlgorithm.Algorithm = oidSignatureEd25519 - - pkix := pkixPublicKey{ - Algo: publicKeyAlgorithm, - BitString: asn1.BitString{ - Bytes: publicKeyBytes, - BitLength: 8 * len(publicKeyBytes), - }, - } - - ret, _ := asn1.Marshal(pkix) - return ret, nil -} diff --git a/vendor/github.com/go-webauthn/webauthn/protocol/webauthncose/webauthncose.go b/vendor/github.com/go-webauthn/webauthn/protocol/webauthncose/webauthncose.go index 308adefb0d3e2f4037ccd8bde6e4eb986b475a7a..b1a974e4fb0833394b1120f316dde4392ab1820b 100644 --- a/vendor/github.com/go-webauthn/webauthn/protocol/webauthncose/webauthncose.go +++ b/vendor/github.com/go-webauthn/webauthn/protocol/webauthncose/webauthncose.go @@ -3,6 +3,7 @@ package webauthncose import ( "crypto" "crypto/ecdsa" + "crypto/ed25519" "crypto/elliptic" "crypto/rsa" "crypto/x509" @@ -13,7 +14,6 @@ import ( "math/big" "github.com/google/go-tpm/legacy/tpm2" - "golang.org/x/crypto/ed25519" "github.com/go-webauthn/webauthn/protocol/webauthncbor" ) @@ -35,6 +35,9 @@ type PublicKeyData struct { // A COSEAlgorithmIdentifier for the algorithm used to derive the key signature. Algorithm int64 `cbor:"3,keyasint" json:"alg"` } + +const ecCoordSize = 32 + type EC2PublicKeyData struct { PublicKeyData @@ -78,16 +81,8 @@ func (k *OKPPublicKeyData) Verify(data []byte, sig []byte) (bool, error) { // Verify Elliptic Curve Public Key Signature. func (k *EC2PublicKeyData) Verify(data []byte, sig []byte) (bool, error) { - var curve elliptic.Curve - - switch COSEAlgorithmIdentifier(k.Algorithm) { - case AlgES512: // IANA COSE code for ECDSA w/ SHA-512. - curve = elliptic.P521() - case AlgES384: // IANA COSE code for ECDSA w/ SHA-384. - curve = elliptic.P384() - case AlgES256: // IANA COSE code for ECDSA w/ SHA-256. - curve = elliptic.P256() - default: + curve := ec2AlgCurve(k.Algorithm) + if curve == nil { return false, ErrUnsupportedAlgorithm } @@ -97,16 +92,13 @@ func (k *EC2PublicKeyData) Verify(data []byte, sig []byte) (bool, error) { Y: big.NewInt(0).SetBytes(k.YCoord), } + h := HasherFromCOSEAlg(COSEAlgorithmIdentifier(k.PublicKeyData.Algorithm)) + h.Write(data) + type ECDSASignature struct { R, S *big.Int } - e := &ECDSASignature{} - f := HasherFromCOSEAlg(COSEAlgorithmIdentifier(k.PublicKeyData.Algorithm)) - h := f() - - h.Write(data) - _, err := asn1.Unmarshal(sig, e) if err != nil { return false, ErrSigNotProvidedOrInvalid @@ -122,26 +114,16 @@ func (k *RSAPublicKeyData) Verify(data []byte, sig []byte) (bool, error) { E: int(uint(k.Exponent[2]) | uint(k.Exponent[1])<<8 | uint(k.Exponent[0])<<16), } - f := HasherFromCOSEAlg(COSEAlgorithmIdentifier(k.PublicKeyData.Algorithm)) - h := f() - h.Write(data) - - var hash crypto.Hash - - switch COSEAlgorithmIdentifier(k.PublicKeyData.Algorithm) { - case AlgRS1: - hash = crypto.SHA1 - case AlgPS256, AlgRS256: - hash = crypto.SHA256 - case AlgPS384, AlgRS384: - hash = crypto.SHA384 - case AlgPS512, AlgRS512: - hash = crypto.SHA512 - default: + coseAlg := COSEAlgorithmIdentifier(k.PublicKeyData.Algorithm) + algDetail, ok := COSESignatureAlgorithmDetails[coseAlg] + if !ok { return false, ErrUnsupportedAlgorithm } + hash := algDetail.hash + h := hash.New() + h.Write(data) - switch COSEAlgorithmIdentifier(k.PublicKeyData.Algorithm) { + switch coseAlg { case AlgPS256, AlgPS384, AlgPS512: err := rsa.VerifyPSS(pubkey, hash, h.Sum(nil), sig, nil) @@ -155,30 +137,8 @@ func (k *RSAPublicKeyData) Verify(data []byte, sig []byte) (bool, error) { } } -// SigAlgFromCOSEAlg return which signature algorithm is being used from the COSE Key. -func SigAlgFromCOSEAlg(coseAlg COSEAlgorithmIdentifier) SignatureAlgorithm { - for _, details := range SignatureAlgorithmDetails { - if details.coseAlg == coseAlg { - return details.algo - } - } - - return UnknownSignatureAlgorithm -} - -// HasherFromCOSEAlg returns the Hashing interface to be used for a given COSE Algorithm. -func HasherFromCOSEAlg(coseAlg COSEAlgorithmIdentifier) func() hash.Hash { - for _, details := range SignatureAlgorithmDetails { - if details.coseAlg == coseAlg { - return details.hasher - } - } - // default to SHA256? Why not. - return crypto.SHA256.New -} - // ParsePublicKey figures out what kind of COSE material was provided and create the data for the new key. -func ParsePublicKey(keyBytes []byte) (interface{}, error) { +func ParsePublicKey(keyBytes []byte) (any, error) { pk := PublicKeyData{} // TODO (james-d-elliott): investigate the ignored errors. webauthncbor.Unmarshal(keyBytes, &pk) @@ -222,11 +182,97 @@ func ParseFIDOPublicKey(keyBytes []byte) (data EC2PublicKeyData, err error) { PublicKeyData: PublicKeyData{ Algorithm: int64(AlgES256), }, - XCoord: x.Bytes(), - YCoord: y.Bytes(), + XCoord: x.FillBytes(make([]byte, ecCoordSize)), + YCoord: y.FillBytes(make([]byte, ecCoordSize)), }, nil } +func VerifySignature(key any, data []byte, sig []byte) (bool, error) { + switch k := key.(type) { + case OKPPublicKeyData: + return k.Verify(data, sig) + case EC2PublicKeyData: + return k.Verify(data, sig) + case RSAPublicKeyData: + return k.Verify(data, sig) + default: + return false, ErrUnsupportedKey + } +} + +func DisplayPublicKey(cpk []byte) string { + parsedKey, err := ParsePublicKey(cpk) + if err != nil { + return keyCannotDisplay + } + + switch k := parsedKey.(type) { + case RSAPublicKeyData: + rKey := &rsa.PublicKey{ + N: big.NewInt(0).SetBytes(k.Modulus), + E: int(uint(k.Exponent[2]) | uint(k.Exponent[1])<<8 | uint(k.Exponent[0])<<16), + } + + data, err := x509.MarshalPKIXPublicKey(rKey) + if err != nil { + return keyCannotDisplay + } + + pemBytes := pem.EncodeToMemory(&pem.Block{ + Type: "RSA PUBLIC KEY", + Bytes: data, + }) + + return string(pemBytes) + case EC2PublicKeyData: + curve := ec2AlgCurve(k.Algorithm) + if curve == nil { + return keyCannotDisplay + } + + eKey := &ecdsa.PublicKey{ + Curve: curve, + X: big.NewInt(0).SetBytes(k.XCoord), + Y: big.NewInt(0).SetBytes(k.YCoord), + } + + data, err := x509.MarshalPKIXPublicKey(eKey) + if err != nil { + return keyCannotDisplay + } + + pemBytes := pem.EncodeToMemory(&pem.Block{ + Type: "PUBLIC KEY", + Bytes: data, + }) + + return string(pemBytes) + case OKPPublicKeyData: + if len(k.XCoord) != ed25519.PublicKeySize { + return keyCannotDisplay + } + + var oKey ed25519.PublicKey = make([]byte, ed25519.PublicKeySize) + + copy(oKey, k.XCoord) + + data, err := marshalEd25519PublicKey(oKey) + if err != nil { + return keyCannotDisplay + } + + pemBytes := pem.EncodeToMemory(&pem.Block{ + Type: "PUBLIC KEY", + Bytes: data, + }) + + return string(pemBytes) + + default: + return "Cannot display key of this type" + } +} + // COSEAlgorithmIdentifier is a number identifying a cryptographic algorithm. The algorithm identifiers SHOULD be values // registered in the IANA COSE Algorithms registry [https://www.w3.org/TR/webauthn/#biblio-iana-cose-algs-reg], for // instance, -7 for "ES256" and -257 for "RS256". @@ -238,24 +284,15 @@ const ( // AlgES256 ECDSA with SHA-256. AlgES256 COSEAlgorithmIdentifier = -7 + // AlgEdDSA EdDSA. + AlgEdDSA COSEAlgorithmIdentifier = -8 + // AlgES384 ECDSA with SHA-384. AlgES384 COSEAlgorithmIdentifier = -35 // AlgES512 ECDSA with SHA-512. AlgES512 COSEAlgorithmIdentifier = -36 - // AlgRS1 RSASSA-PKCS1-v1_5 with SHA-1. - AlgRS1 COSEAlgorithmIdentifier = -65535 - - // AlgRS256 RSASSA-PKCS1-v1_5 with SHA-256. - AlgRS256 COSEAlgorithmIdentifier = -257 - - // AlgRS384 RSASSA-PKCS1-v1_5 with SHA-384. - AlgRS384 COSEAlgorithmIdentifier = -258 - - // AlgRS512 RSASSA-PKCS1-v1_5 with SHA-512. - AlgRS512 COSEAlgorithmIdentifier = -259 - // AlgPS256 RSASSA-PSS with SHA-256. AlgPS256 COSEAlgorithmIdentifier = -37 @@ -265,11 +302,20 @@ const ( // AlgPS512 RSASSA-PSS with SHA-512. AlgPS512 COSEAlgorithmIdentifier = -39 - // AlgEdDSA EdDSA. - AlgEdDSA COSEAlgorithmIdentifier = -8 - // AlgES256K is ECDSA using secp256k1 curve and SHA-256. AlgES256K COSEAlgorithmIdentifier = -47 + + // AlgRS256 RSASSA-PKCS1-v1_5 with SHA-256. + AlgRS256 COSEAlgorithmIdentifier = -257 + + // AlgRS384 RSASSA-PKCS1-v1_5 with SHA-384. + AlgRS384 COSEAlgorithmIdentifier = -258 + + // AlgRS512 RSASSA-PKCS1-v1_5 with SHA-512. + AlgRS512 COSEAlgorithmIdentifier = -259 + + // AlgRS1 RSASSA-PKCS1-v1_5 with SHA-1. + AlgRS1 COSEAlgorithmIdentifier = -65535 ) // COSEKeyType is The Key type derived from the IANA COSE AuthData. @@ -342,139 +388,54 @@ func (k *EC2PublicKeyData) TPMCurveID() tpm2.EllipticCurve { } } -func VerifySignature(key interface{}, data []byte, sig []byte) (bool, error) { - switch k := key.(type) { - case OKPPublicKeyData: - return k.Verify(data, sig) - case EC2PublicKeyData: - return k.Verify(data, sig) - case RSAPublicKeyData: - return k.Verify(data, sig) +func ec2AlgCurve(coseAlg int64) elliptic.Curve { + switch COSEAlgorithmIdentifier(coseAlg) { + case AlgES512: // IANA COSE code for ECDSA w/ SHA-512. + return elliptic.P521() + case AlgES384: // IANA COSE code for ECDSA w/ SHA-384. + return elliptic.P384() + case AlgES256: // IANA COSE code for ECDSA w/ SHA-256. + return elliptic.P256() default: - return false, ErrUnsupportedKey + return nil } } -func DisplayPublicKey(cpk []byte) string { - parsedKey, err := ParsePublicKey(cpk) - if err != nil { - return keyCannotDisplay +// SigAlgFromCOSEAlg return which signature algorithm is being used from the COSE Key. +func SigAlgFromCOSEAlg(coseAlg COSEAlgorithmIdentifier) x509.SignatureAlgorithm { + d, ok := COSESignatureAlgorithmDetails[coseAlg] + if !ok { + return x509.UnknownSignatureAlgorithm } + return d.sigAlg +} - switch k := parsedKey.(type) { - case RSAPublicKeyData: - rKey := &rsa.PublicKey{ - N: big.NewInt(0).SetBytes(k.Modulus), - E: int(uint(k.Exponent[2]) | uint(k.Exponent[1])<<8 | uint(k.Exponent[0])<<16), - } - - data, err := x509.MarshalPKIXPublicKey(rKey) - if err != nil { - return keyCannotDisplay - } - - pemBytes := pem.EncodeToMemory(&pem.Block{ - Type: "RSA PUBLIC KEY", - Bytes: data, - }) - - return string(pemBytes) - case EC2PublicKeyData: - var curve elliptic.Curve - - switch COSEAlgorithmIdentifier(k.Algorithm) { - case AlgES256: - curve = elliptic.P256() - case AlgES384: - curve = elliptic.P384() - case AlgES512: - curve = elliptic.P521() - default: - return keyCannotDisplay - } - - eKey := &ecdsa.PublicKey{ - Curve: curve, - X: big.NewInt(0).SetBytes(k.XCoord), - Y: big.NewInt(0).SetBytes(k.YCoord), - } - - data, err := x509.MarshalPKIXPublicKey(eKey) - if err != nil { - return keyCannotDisplay - } - - pemBytes := pem.EncodeToMemory(&pem.Block{ - Type: "PUBLIC KEY", - Bytes: data, - }) - - return string(pemBytes) - case OKPPublicKeyData: - if len(k.XCoord) != ed25519.PublicKeySize { - return keyCannotDisplay - } - - var oKey ed25519.PublicKey = make([]byte, ed25519.PublicKeySize) - - copy(oKey, k.XCoord) - - data, err := marshalEd25519PublicKey(oKey) - if err != nil { - return keyCannotDisplay - } - - pemBytes := pem.EncodeToMemory(&pem.Block{ - Type: "PUBLIC KEY", - Bytes: data, - }) - - return string(pemBytes) - - default: - return "Cannot display key of this type" +// HasherFromCOSEAlg returns the Hashing interface to be used for a given COSE Algorithm. +func HasherFromCOSEAlg(coseAlg COSEAlgorithmIdentifier) hash.Hash { + d, ok := COSESignatureAlgorithmDetails[coseAlg] + if !ok { + // default to SHA256? Why not. + return crypto.SHA256.New() } + return d.hash.New() } -// SignatureAlgorithm represents algorithm enumerations used for COSE signatures. -type SignatureAlgorithm int - -const ( - UnknownSignatureAlgorithm SignatureAlgorithm = iota - MD2WithRSA - MD5WithRSA - SHA1WithRSA - SHA256WithRSA - SHA384WithRSA - SHA512WithRSA - DSAWithSHA1 - DSAWithSHA256 - ECDSAWithSHA1 - ECDSAWithSHA256 - ECDSAWithSHA384 - ECDSAWithSHA512 - SHA256WithRSAPSS - SHA384WithRSAPSS - SHA512WithRSAPSS -) - -var SignatureAlgorithmDetails = []struct { - algo SignatureAlgorithm - coseAlg COSEAlgorithmIdentifier - name string - hasher func() hash.Hash +var COSESignatureAlgorithmDetails = map[COSEAlgorithmIdentifier]struct { + name string + hash crypto.Hash + sigAlg x509.SignatureAlgorithm }{ - {SHA1WithRSA, AlgRS1, "SHA1-RSA", crypto.SHA1.New}, - {SHA256WithRSA, AlgRS256, "SHA256-RSA", crypto.SHA256.New}, - {SHA384WithRSA, AlgRS384, "SHA384-RSA", crypto.SHA384.New}, - {SHA512WithRSA, AlgRS512, "SHA512-RSA", crypto.SHA512.New}, - {SHA256WithRSAPSS, AlgPS256, "SHA256-RSAPSS", crypto.SHA256.New}, - {SHA384WithRSAPSS, AlgPS384, "SHA384-RSAPSS", crypto.SHA384.New}, - {SHA512WithRSAPSS, AlgPS512, "SHA512-RSAPSS", crypto.SHA512.New}, - {ECDSAWithSHA256, AlgES256, "ECDSA-SHA256", crypto.SHA256.New}, - {ECDSAWithSHA384, AlgES384, "ECDSA-SHA384", crypto.SHA384.New}, - {ECDSAWithSHA512, AlgES512, "ECDSA-SHA512", crypto.SHA512.New}, - {UnknownSignatureAlgorithm, AlgEdDSA, "EdDSA", crypto.SHA512.New}, + AlgRS1: {"SHA1-RSA", crypto.SHA1, x509.SHA1WithRSA}, + AlgRS256: {"SHA256-RSA", crypto.SHA256, x509.SHA256WithRSA}, + AlgRS384: {"SHA384-RSA", crypto.SHA384, x509.SHA384WithRSA}, + AlgRS512: {"SHA512-RSA", crypto.SHA512, x509.SHA512WithRSA}, + AlgPS256: {"SHA256-RSAPSS", crypto.SHA256, x509.SHA256WithRSAPSS}, + AlgPS384: {"SHA384-RSAPSS", crypto.SHA384, x509.SHA384WithRSAPSS}, + AlgPS512: {"SHA512-RSAPSS", crypto.SHA512, x509.SHA512WithRSAPSS}, + AlgES256: {"ECDSA-SHA256", crypto.SHA256, x509.ECDSAWithSHA256}, + AlgES384: {"ECDSA-SHA384", crypto.SHA384, x509.ECDSAWithSHA384}, + AlgES512: {"ECDSA-SHA512", crypto.SHA512, x509.ECDSAWithSHA512}, + AlgEdDSA: {"EdDSA", crypto.SHA512, x509.PureEd25519}, } type Error struct { diff --git a/vendor/github.com/go-webauthn/webauthn/webauthn/const.go b/vendor/github.com/go-webauthn/webauthn/webauthn/const.go index 9ab74f2c7e621cfc08faabec3e5e9cb81f748815..7f08c3d0067731a3d1fa29c9853b4276a9a61592 100644 --- a/vendor/github.com/go-webauthn/webauthn/webauthn/const.go +++ b/vendor/github.com/go-webauthn/webauthn/webauthn/const.go @@ -5,7 +5,6 @@ import ( ) const ( - errFmtFieldEmpty = "the field '%s' must be configured but it is empty" errFmtFieldNotValidURI = "field '%s' is not a valid URI: %w" errFmtConfigValidate = "error occurred validating the configuration: %w" ) diff --git a/vendor/github.com/go-webauthn/webauthn/webauthn/credential.go b/vendor/github.com/go-webauthn/webauthn/webauthn/credential.go index 81bcc9ada7a54242b148971ecf828ccd15fbfd65..51b4fa4d0da28dba9f7fd09f3fb6919e7f426019 100644 --- a/vendor/github.com/go-webauthn/webauthn/webauthn/credential.go +++ b/vendor/github.com/go-webauthn/webauthn/webauthn/credential.go @@ -1,18 +1,22 @@ package webauthn import ( + "crypto/sha256" + "fmt" + + "github.com/go-webauthn/webauthn/metadata" "github.com/go-webauthn/webauthn/protocol" ) -// Credential contains all needed information about a WebAuthn credential for storage. +// Credential contains all needed information about a WebAuthn credential for storage. This struct is effectively the +// Credential Record as described in the specification. +// +// See: §4. Terminology: Credential Record (https://www.w3.org/TR/webauthn-3/#credential-record) type Credential struct { - // A probabilistically-unique byte sequence identifying a public key credential source and its authentication assertions. + // The Credential ID of the public key credential source. Described by the Credential Record 'id' field. ID []byte `json:"id"` - // The public key portion of a Relying Party-specific credential key pair, generated by an authenticator and returned to - // a Relying Party at registration time (see also public key credential). The private key portion of the credential key - // pair is known as the credential private key. Note that in the case of self attestation, the credential key pair is also - // used as the attestation key pair, see self attestation for details. + // The credential public key of the public key credential source. Described by the Credential Record 'publicKey field. PublicKey []byte `json:"publicKey"` // The attestation format used (if any) by the authenticator when creating the credential. @@ -26,6 +30,22 @@ type Credential struct { // The Authenticator information for a given certificate. Authenticator Authenticator `json:"authenticator"` + + // The attestation values that can be used to validate this credential via the MDS3 at a later date. + Attestation CredentialAttestation `json:"attestation"` +} + +// NewCredentialFlags is a utility function that is used to derive the Credential's Flags field. This allows +// implementers to solely save the Raw field of the CredentialFlags to restore them appropriately for appropriate +// processing without concern that changes forced upon implementers by the W3C will introduce breaking changes. +func NewCredentialFlags(flags protocol.AuthenticatorFlags) CredentialFlags { + return CredentialFlags{ + UserPresent: flags.HasUserPresent(), + UserVerified: flags.HasUserVerified(), + BackupEligible: flags.HasBackupEligible(), + BackupState: flags.HasBackupState(), + raw: flags, + } } type CredentialFlags struct { @@ -41,6 +61,22 @@ type CredentialFlags struct { // Flag BS indicates the credential has been backed up and/or sync'd. This value can change but it's recommended // that RP's keep track of this value. BackupState bool `json:"backupState"` + + raw protocol.AuthenticatorFlags +} + +// ProtocolValue returns the underlying protocol.AuthenticatorFlags provided this CredentialFlags was created using +// NewCredentialFlags. +func (f CredentialFlags) ProtocolValue() protocol.AuthenticatorFlags { + return f.raw +} + +type CredentialAttestation struct { + ClientDataJSON []byte `json:"clientDataJSON"` + ClientDataHash []byte `json:"clientDataHash"` + AuthenticatorData []byte `json:"authenticatorData"` + PublicKeyAlgorithm int64 `json:"publicKeyAlgorithm"` + Object []byte `json:"object"` } // Descriptor converts a Credential into a protocol.CredentialDescriptor. @@ -53,25 +89,69 @@ func (c Credential) Descriptor() (descriptor protocol.CredentialDescriptor) { } } -// MakeNewCredential will return a credential pointer on successful validation of a registration response. -func MakeNewCredential(c *protocol.ParsedCredentialCreationData) (*Credential, error) { - newCredential := &Credential{ +// NewCredential will return a credential pointer on successful validation of a registration response. +func NewCredential(clientDataHash []byte, c *protocol.ParsedCredentialCreationData) (credential *Credential, err error) { + credential = &Credential{ ID: c.Response.AttestationObject.AuthData.AttData.CredentialID, PublicKey: c.Response.AttestationObject.AuthData.AttData.CredentialPublicKey, AttestationType: c.Response.AttestationObject.Format, Transport: c.Response.Transports, - Flags: CredentialFlags{ - UserPresent: c.Response.AttestationObject.AuthData.Flags.HasUserPresent(), - UserVerified: c.Response.AttestationObject.AuthData.Flags.HasUserVerified(), - BackupEligible: c.Response.AttestationObject.AuthData.Flags.HasBackupEligible(), - BackupState: c.Response.AttestationObject.AuthData.Flags.HasBackupState(), - }, + Flags: NewCredentialFlags(c.Response.AttestationObject.AuthData.Flags), Authenticator: Authenticator{ AAGUID: c.Response.AttestationObject.AuthData.AttData.AAGUID, SignCount: c.Response.AttestationObject.AuthData.Counter, Attachment: c.AuthenticatorAttachment, }, + Attestation: CredentialAttestation{ + ClientDataJSON: c.Raw.AttestationResponse.ClientDataJSON, + ClientDataHash: clientDataHash, + AuthenticatorData: c.Raw.AttestationResponse.AuthenticatorData, + PublicKeyAlgorithm: c.Raw.AttestationResponse.PublicKeyAlgorithm, + Object: c.Raw.AttestationResponse.AttestationObject, + }, + } + + return credential, nil +} + +// Verify this credentials against the metadata.Provider given. +func (c Credential) Verify(mds metadata.Provider) (err error) { + if mds == nil { + return fmt.Errorf("error verifying credential: the metadata provider must be provided but it's nil") + } + + raw := &protocol.AuthenticatorAttestationResponse{ + AuthenticatorResponse: protocol.AuthenticatorResponse{ + ClientDataJSON: c.Attestation.ClientDataJSON, + }, + Transports: make([]string, len(c.Transport)), + AuthenticatorData: c.Attestation.AuthenticatorData, + PublicKey: c.PublicKey, + PublicKeyAlgorithm: c.Attestation.PublicKeyAlgorithm, + AttestationObject: c.Attestation.Object, + } + + for i, transport := range c.Transport { + raw.Transports[i] = string(transport) + } + + var attestation *protocol.ParsedAttestationResponse + + if attestation, err = raw.Parse(); err != nil { + return fmt.Errorf("error verifying credential: error parsing attestation: %w", err) + } + + clientDataHash := c.Attestation.ClientDataHash + + if len(clientDataHash) == 0 { + sum := sha256.Sum256(c.Attestation.ClientDataJSON) + + clientDataHash = sum[:] + } + + if err = attestation.AttestationObject.VerifyAttestation(clientDataHash, mds); err != nil { + return fmt.Errorf("error verifying credential: error verifying attestation: %w", err) } - return newCredential, nil + return nil } diff --git a/vendor/github.com/go-webauthn/webauthn/webauthn/login.go b/vendor/github.com/go-webauthn/webauthn/webauthn/login.go index 73e69af462b017475ccec8143a0426985eee4682..a474ec6063585f807f85ee5eda984b91e30f0044 100644 --- a/vendor/github.com/go-webauthn/webauthn/webauthn/login.go +++ b/vendor/github.com/go-webauthn/webauthn/webauthn/login.go @@ -2,10 +2,14 @@ package webauthn import ( "bytes" + "context" "fmt" "net/http" + "net/url" "time" + "github.com/google/uuid" + "github.com/go-webauthn/webauthn/protocol" ) @@ -27,6 +31,16 @@ type DiscoverableUserHandler func(rawID, userHandle []byte) (user User, err erro // // Specification: §5.5. Options for Assertion Generation (https://www.w3.org/TR/webauthn/#dictionary-assertion-options) func (webauthn *WebAuthn) BeginLogin(user User, opts ...LoginOption) (*protocol.CredentialAssertion, *SessionData, error) { + return webauthn.BeginMediatedLogin(user, "", opts...) +} + +// BeginDiscoverableLogin begins a client-side discoverable login, previously known as Resident Key logins. +func (webauthn *WebAuthn) BeginDiscoverableLogin(opts ...LoginOption) (*protocol.CredentialAssertion, *SessionData, error) { + return webauthn.beginLogin(nil, nil, "", opts...) +} + +// BeginMediatedLogin is similar to BeginLogin however it also allows specifying a credential mediation requirement. +func (webauthn *WebAuthn) BeginMediatedLogin(user User, mediation protocol.CredentialMediationRequirement, opts ...LoginOption) (*protocol.CredentialAssertion, *SessionData, error) { credentials := user.WebAuthnCredentials() if len(credentials) == 0 { // If the user does not have any credentials, we cannot perform an assertion. @@ -39,37 +53,51 @@ func (webauthn *WebAuthn) BeginLogin(user User, opts ...LoginOption) (*protocol. allowedCredentials[i] = credential.Descriptor() } - return webauthn.beginLogin(user.WebAuthnID(), allowedCredentials, opts...) + return webauthn.beginLogin(user.WebAuthnID(), allowedCredentials, mediation, opts...) } -// BeginDiscoverableLogin begins a client-side discoverable login, previously known as Resident Key logins. -func (webauthn *WebAuthn) BeginDiscoverableLogin(opts ...LoginOption) (*protocol.CredentialAssertion, *SessionData, error) { - return webauthn.beginLogin(nil, nil, opts...) +// BeginDiscoverableMediatedLogin begins a client-side discoverable login with a mediation requirement, previously known +// as Resident Key logins. +func (webauthn *WebAuthn) BeginDiscoverableMediatedLogin(mediation protocol.CredentialMediationRequirement, opts ...LoginOption) (*protocol.CredentialAssertion, *SessionData, error) { + return webauthn.beginLogin(nil, nil, mediation, opts...) } -func (webauthn *WebAuthn) beginLogin(userID []byte, allowedCredentials []protocol.CredentialDescriptor, opts ...LoginOption) (assertion *protocol.CredentialAssertion, session *SessionData, err error) { +func (webauthn *WebAuthn) beginLogin(userID []byte, allowedCredentials []protocol.CredentialDescriptor, mediation protocol.CredentialMediationRequirement, opts ...LoginOption) (assertion *protocol.CredentialAssertion, session *SessionData, err error) { if err = webauthn.Config.validate(); err != nil { return nil, nil, fmt.Errorf(errFmtConfigValidate, err) } - challenge, err := protocol.CreateChallenge() - if err != nil { - return nil, nil, err - } - assertion = &protocol.CredentialAssertion{ Response: protocol.PublicKeyCredentialRequestOptions{ - Challenge: challenge, RelyingPartyID: webauthn.Config.RPID, UserVerification: webauthn.Config.AuthenticatorSelection.UserVerification, AllowedCredentials: allowedCredentials, }, + Mediation: mediation, } for _, opt := range opts { opt(&assertion.Response) } + if len(assertion.Response.Challenge) == 0 { + challenge, err := protocol.CreateChallenge() + if err != nil { + return nil, nil, err + } + assertion.Response.Challenge = challenge + } + + if len(assertion.Response.Challenge) < 16 { + return nil, nil, fmt.Errorf("error generating assertion: the challenge must be at least 16 bytes") + } + + if len(assertion.Response.RelyingPartyID) == 0 { + return nil, nil, fmt.Errorf("error generating assertion: the relying party id must be provided via the configuration or a functional option for a login") + } else if _, err = url.Parse(assertion.Response.RelyingPartyID); err != nil { + return nil, nil, fmt.Errorf("error generating assertion: the relying party id failed to validate as it's not a valid uri with error: %w", err) + } + if assertion.Response.Timeout == 0 { switch { case assertion.Response.UserVerification == protocol.VerificationDiscouraged: @@ -80,7 +108,8 @@ func (webauthn *WebAuthn) beginLogin(userID []byte, allowedCredentials []protoco } session = &SessionData{ - Challenge: challenge.String(), + Challenge: assertion.Response.Challenge.String(), + RelyingPartyID: assertion.Response.RelyingPartyID, UserID: userID, AllowedCredentialIDs: assertion.Response.GetAllowedCredentialIDs(), UserVerification: assertion.Response.UserVerification, @@ -115,6 +144,15 @@ func WithUserVerification(userVerification protocol.UserVerificationRequirement) } } +// WithAssertionPublicKeyCredentialHints adjusts the non-default hints for credential types to select during login. +// +// WebAuthn Level 3. +func WithAssertionPublicKeyCredentialHints(hints []protocol.PublicKeyCredentialHints) LoginOption { + return func(cco *protocol.PublicKeyCredentialRequestOptions) { + cco.Hints = hints + } +} + // WithAssertionExtensions adjusts the requested extensions. func WithAssertionExtensions(extensions protocol.AuthenticationExtensions) LoginOption { return func(cco *protocol.PublicKeyCredentialRequestOptions) { @@ -129,7 +167,7 @@ func WithAppIdExtension(appid string) LoginOption { for _, credential := range cco.AllowedCredentials { if credential.AttestationType == protocol.CredentialTypeFIDOU2F { if cco.Extensions == nil { - cco.Extensions = map[string]interface{}{} + cco.Extensions = map[string]any{} } cco.Extensions[protocol.ExtensionAppID] = appid @@ -138,6 +176,25 @@ func WithAppIdExtension(appid string) LoginOption { } } +// WithLoginRelyingPartyID sets the Relying Party ID for this particular login. +func WithLoginRelyingPartyID(id string) LoginOption { + return func(cco *protocol.PublicKeyCredentialRequestOptions) { + cco.RelyingPartyID = id + } +} + +// WithChallenge overrides the default random challenge with a user supplied value. +// In order to prevent replay attacks, the challenges MUST contain enough entropy to make guessing them infeasible. +// Challenges SHOULD therefore be at least 16 bytes long. +// This function is EXPERIMENTAL and can be removed without warning. +// +// Specification: §13.4.3. Cryptographic Challenges (https://www.w3.org/TR/webauthn/#sctn-cryptographic-challenges) +func WithChallenge(challenge []byte) LoginOption { + return func(cco *protocol.PublicKeyCredentialRequestOptions) { + cco.Challenge = challenge + } +} + // FinishLogin takes the response from the client and validate it against the user credentials and stored session data. func (webauthn *WebAuthn) FinishLogin(user User, session SessionData, response *http.Request) (*Credential, error) { parsedResponse, err := protocol.ParseCredentialRequestResponse(response) @@ -174,21 +231,33 @@ func (webauthn *WebAuthn) ValidateLogin(user User, session SessionData, parsedRe } // ValidateDiscoverableLogin is an overloaded version of ValidateLogin that allows for discoverable credentials. -func (webauthn *WebAuthn) ValidateDiscoverableLogin(handler DiscoverableUserHandler, session SessionData, parsedResponse *protocol.ParsedCredentialAssertionData) (*Credential, error) { - if session.UserID != nil { - return nil, protocol.ErrBadRequest.WithDetails("Session was not initiated as a client-side discoverable login") +// +// Note: this is just a backwards compatibility layer over ValidatePasskeyLogin which returns more information. +func (webauthn *WebAuthn) ValidateDiscoverableLogin(handler DiscoverableUserHandler, session SessionData, parsedResponse *protocol.ParsedCredentialAssertionData) (credential *Credential, err error) { + _, credential, err = webauthn.ValidatePasskeyLogin(handler, session, parsedResponse) + + return credential, err +} + +// ValidatePasskeyLogin is an overloaded version of ValidateLogin that allows for passkey credentials. +func (webauthn *WebAuthn) ValidatePasskeyLogin(handler DiscoverableUserHandler, session SessionData, parsedResponse *protocol.ParsedCredentialAssertionData) (user User, credential *Credential, err error) { + if len(session.UserID) != 0 { + return nil, nil, protocol.ErrBadRequest.WithDetails("Session was not initiated as a client-side discoverable login") } - if parsedResponse.Response.UserHandle == nil { - return nil, protocol.ErrBadRequest.WithDetails("Client-side Discoverable Assertion was attempted with a blank User Handle") + if len(parsedResponse.Response.UserHandle) == 0 { + return nil, nil, protocol.ErrBadRequest.WithDetails("Client-side Discoverable Assertion was attempted with a blank User Handle") } - user, err := handler(parsedResponse.RawID, parsedResponse.Response.UserHandle) - if err != nil { - return nil, protocol.ErrBadRequest.WithDetails(fmt.Sprintf("Failed to lookup Client-side Discoverable Credential: %s", err)) + if user, err = handler(parsedResponse.RawID, parsedResponse.Response.UserHandle); err != nil { + return nil, nil, protocol.ErrBadRequest.WithDetails(fmt.Sprintf("Failed to lookup Client-side Discoverable Credential: %s", err)).WithError(err) } - return webauthn.validateLogin(user, session, parsedResponse) + if credential, err = webauthn.validateLogin(user, session, parsedResponse); err != nil { + return nil, nil, err + } + + return user, credential, nil } // ValidateLogin takes a parsed response and validates it against the user credentials and session data. @@ -198,16 +267,19 @@ func (webauthn *WebAuthn) validateLogin(user User, session SessionData, parsedRe // allowCredentials. // NON-NORMATIVE Prior Step: Verify that the allowCredentials for the session are owned by the user provided. - userCredentials := user.WebAuthnCredentials() + credentials := user.WebAuthnCredentials() - var credentialFound bool + var ( + found bool + credential Credential + ) if len(session.AllowedCredentialIDs) > 0 { var credentialsOwned bool for _, allowedCredentialID := range session.AllowedCredentialIDs { - for _, userCredential := range userCredentials { - if bytes.Equal(userCredential.ID, allowedCredentialID) { + for _, credential = range credentials { + if bytes.Equal(credential.ID, allowedCredentialID) { credentialsOwned = true break @@ -223,13 +295,13 @@ func (webauthn *WebAuthn) validateLogin(user User, session SessionData, parsedRe for _, allowedCredentialID := range session.AllowedCredentialIDs { if bytes.Equal(parsedResponse.RawID, allowedCredentialID) { - credentialFound = true + found = true break } } - if !credentialFound { + if !found { return nil, protocol.ErrBadRequest.WithDetails("User does not own the credential returned") } } @@ -248,48 +320,72 @@ func (webauthn *WebAuthn) validateLogin(user User, session SessionData, parsedRe // Step 3. Using credential’s id attribute (or the corresponding rawId, if base64url encoding is inappropriate // for your use case), look up the corresponding credential public key. - var loginCredential Credential - - for _, cred := range userCredentials { - if bytes.Equal(cred.ID, parsedResponse.RawID) { - loginCredential = cred - credentialFound = true + for _, credential = range credentials { + if bytes.Equal(credential.ID, parsedResponse.RawID) { + found = true break } - credentialFound = false + found = false } - if !credentialFound { + if !found { return nil, protocol.ErrBadRequest.WithDetails("Unable to find the credential for the returned credential ID") } + var ( + appID string + err error + ) + + // Ensure authenticators with a bad status is not used. + if webauthn.Config.MDS != nil { + var aaguid uuid.UUID + + if aaguid, err = uuid.FromBytes(credential.Authenticator.AAGUID); err != nil { + return nil, protocol.ErrBadRequest.WithDetails("Failed to decode AAGUID").WithInfo(fmt.Sprintf("Error occurred decoding AAGUID from the credential record: %s", err)).WithError(err) + } + + var protoErr *protocol.Error + + if protoErr = protocol.ValidateMetadata(context.Background(), webauthn.Config.MDS, aaguid, "", nil); protoErr != nil { + return nil, protocol.ErrBadRequest.WithDetails("Failed to validate credential record metadata").WithInfo(protoErr.DevInfo).WithError(protoErr) + } + } + shouldVerifyUser := session.UserVerification == protocol.VerificationRequired rpID := webauthn.Config.RPID rpOrigins := webauthn.Config.RPOrigins + rpTopOrigins := webauthn.Config.RPTopOrigins - appID, err := parsedResponse.GetAppID(session.Extensions, loginCredential.AttestationType) - if err != nil { + if appID, err = parsedResponse.GetAppID(session.Extensions, credential.AttestationType); err != nil { return nil, err } // Handle steps 4 through 16. - validError := parsedResponse.Verify(session.Challenge, rpID, rpOrigins, appID, shouldVerifyUser, loginCredential.PublicKey) - if validError != nil { - return nil, validError + if err = parsedResponse.Verify(session.Challenge, rpID, rpOrigins, rpTopOrigins, webauthn.Config.RPTopOriginVerificationMode, appID, shouldVerifyUser, credential.PublicKey); err != nil { + return nil, err } // Handle step 17. - loginCredential.Authenticator.UpdateCounter(parsedResponse.Response.AuthenticatorData.Counter) + credential.Authenticator.UpdateCounter(parsedResponse.Response.AuthenticatorData.Counter) + // Check if the BackupEligible flag has changed. + if credential.Flags.BackupEligible != parsedResponse.Response.AuthenticatorData.Flags.HasBackupEligible() { + return nil, protocol.ErrBadRequest.WithDetails("BackupEligible flag inconsistency detected during login validation") + } + + // Check for the invalid combination BE=0 and BS=1. + if !parsedResponse.Response.AuthenticatorData.Flags.HasBackupEligible() && parsedResponse.Response.AuthenticatorData.Flags.HasBackupState() { + return nil, protocol.ErrBadRequest.WithDetails("Invalid flag combination: BE=0 and BS=1") + } - // TODO: The backup eligible flag shouldn't change. Should decide if we want to error if it does. // Update flags from response data. - loginCredential.Flags.UserPresent = parsedResponse.Response.AuthenticatorData.Flags.HasUserPresent() - loginCredential.Flags.UserVerified = parsedResponse.Response.AuthenticatorData.Flags.HasUserVerified() - loginCredential.Flags.BackupEligible = parsedResponse.Response.AuthenticatorData.Flags.HasBackupEligible() - loginCredential.Flags.BackupState = parsedResponse.Response.AuthenticatorData.Flags.HasBackupState() + credential.Flags.UserPresent = parsedResponse.Response.AuthenticatorData.Flags.HasUserPresent() + credential.Flags.UserVerified = parsedResponse.Response.AuthenticatorData.Flags.HasUserVerified() + credential.Flags.BackupEligible = parsedResponse.Response.AuthenticatorData.Flags.HasBackupEligible() + credential.Flags.BackupState = parsedResponse.Response.AuthenticatorData.Flags.HasBackupState() - return &loginCredential, nil + return &credential, nil } diff --git a/vendor/github.com/go-webauthn/webauthn/webauthn/registration.go b/vendor/github.com/go-webauthn/webauthn/webauthn/registration.go index 9715246fef1411fcf4ae565b0716689ade4c298e..be921be887fda6e6fe802f3d2b9f607534e0adb1 100644 --- a/vendor/github.com/go-webauthn/webauthn/webauthn/registration.go +++ b/vendor/github.com/go-webauthn/webauthn/webauthn/registration.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "net/http" + "net/url" "time" "github.com/go-webauthn/webauthn/protocol" @@ -20,6 +21,11 @@ type RegistrationOption func(*protocol.PublicKeyCredentialCreationOptions) // BeginRegistration generates a new set of registration data to be sent to the client and authenticator. func (webauthn *WebAuthn) BeginRegistration(user User, opts ...RegistrationOption) (creation *protocol.CredentialCreation, session *SessionData, err error) { + return webauthn.BeginMediatedRegistration(user, "", opts...) +} + +// BeginMediatedRegistration is similar to BeginRegistration however it also allows specifying a credential mediation requirement. +func (webauthn *WebAuthn) BeginMediatedRegistration(user User, mediation protocol.CredentialMediationRequirement, opts ...RegistrationOption) (creation *protocol.CredentialCreation, session *SessionData, err error) { if err = webauthn.Config.validate(); err != nil { return nil, nil, fmt.Errorf(errFmtConfigValidate, err) } @@ -29,7 +35,7 @@ func (webauthn *WebAuthn) BeginRegistration(user User, opts ...RegistrationOptio return nil, nil, err } - var entityUserID interface{} + var entityUserID any if webauthn.Config.EncodeUserIDAsString { entityUserID = string(user.WebAuthnID()) @@ -42,7 +48,6 @@ func (webauthn *WebAuthn) BeginRegistration(user User, opts ...RegistrationOptio DisplayName: user.WebAuthnDisplayName(), CredentialEntity: protocol.CredentialEntity{ Name: user.WebAuthnName(), - Icon: user.WebAuthnIcon(), }, } @@ -50,11 +55,10 @@ func (webauthn *WebAuthn) BeginRegistration(user User, opts ...RegistrationOptio ID: webauthn.Config.RPID, CredentialEntity: protocol.CredentialEntity{ Name: webauthn.Config.RPDisplayName, - Icon: webauthn.Config.RPIcon, }, } - credentialParams := defaultRegistrationCredentialParameters() + credentialParams := CredentialParametersDefault() creation = &protocol.CredentialCreation{ Response: protocol.PublicKeyCredentialCreationOptions{ @@ -65,12 +69,23 @@ func (webauthn *WebAuthn) BeginRegistration(user User, opts ...RegistrationOptio AuthenticatorSelection: webauthn.Config.AuthenticatorSelection, Attestation: webauthn.Config.AttestationPreference, }, + Mediation: mediation, } for _, opt := range opts { opt(&creation.Response) } + if len(creation.Response.RelyingParty.ID) == 0 { + return nil, nil, fmt.Errorf("error generating credential creation: the relying party id must be provided via the configuration or a functional option for a creation") + } else if _, err = url.Parse(creation.Response.RelyingParty.ID); err != nil { + return nil, nil, fmt.Errorf("error generating credential creation: the relying party id failed to validate as it's not a valid uri with error: %w", err) + } + + if len(creation.Response.RelyingParty.Name) == 0 { + return nil, nil, fmt.Errorf("error generating credential creation: the relying party display name must be provided via the configuration or a functional option for a creation") + } + if creation.Response.Timeout == 0 { switch { case creation.Response.AuthenticatorSelection.UserVerification == protocol.VerificationDiscouraged: @@ -82,6 +97,7 @@ func (webauthn *WebAuthn) BeginRegistration(user User, opts ...RegistrationOptio session = &SessionData{ Challenge: challenge.String(), + RelyingPartyID: creation.Response.RelyingParty.ID, UserID: user.WebAuthnID(), UserVerification: creation.Response.AuthenticatorSelection.UserVerification, } @@ -93,6 +109,20 @@ func (webauthn *WebAuthn) BeginRegistration(user User, opts ...RegistrationOptio return creation, session, nil } +// WithCredentialParameters adjusts the credential parameters in the registration options. +func WithCredentialParameters(credentialParams []protocol.CredentialParameter) RegistrationOption { + return func(cco *protocol.PublicKeyCredentialCreationOptions) { + cco.Parameters = credentialParams + } +} + +// WithExclusions adjusts the non-default parameters regarding credentials to exclude from registration. +func WithExclusions(excludeList []protocol.CredentialDescriptor) RegistrationOption { + return func(cco *protocol.PublicKeyCredentialCreationOptions) { + cco.CredentialExcludeList = excludeList + } +} + // WithAuthenticatorSelection adjusts the non-default parameters regarding the authenticator to select during // registration. func WithAuthenticatorSelection(authenticatorSelection protocol.AuthenticatorSelection) RegistrationOption { @@ -101,10 +131,26 @@ func WithAuthenticatorSelection(authenticatorSelection protocol.AuthenticatorSel } } -// WithExclusions adjusts the non-default parameters regarding credentials to exclude from registration. -func WithExclusions(excludeList []protocol.CredentialDescriptor) RegistrationOption { +// WithResidentKeyRequirement sets both the resident key and require resident key protocol options. +func WithResidentKeyRequirement(requirement protocol.ResidentKeyRequirement) RegistrationOption { return func(cco *protocol.PublicKeyCredentialCreationOptions) { - cco.CredentialExcludeList = excludeList + cco.AuthenticatorSelection.ResidentKey = requirement + + switch requirement { + case protocol.ResidentKeyRequirementRequired: + cco.AuthenticatorSelection.RequireResidentKey = protocol.ResidentKeyRequired() + default: + cco.AuthenticatorSelection.RequireResidentKey = protocol.ResidentKeyNotRequired() + } + } +} + +// WithPublicKeyCredentialHints adjusts the non-default hints for credential types to select during registration. +// +// WebAuthn Level 3. +func WithPublicKeyCredentialHints(hints []protocol.PublicKeyCredentialHints) RegistrationOption { + return func(cco *protocol.PublicKeyCredentialCreationOptions) { + cco.Hints = hints } } @@ -116,17 +162,19 @@ func WithConveyancePreference(preference protocol.ConveyancePreference) Registra } } -// WithExtensions adjusts the extension parameter in the registration options. -func WithExtensions(extension protocol.AuthenticationExtensions) RegistrationOption { +// WithAttestationFormats adjusts the non-default formats for credential types to select during registration. +// +// WebAuthn Level 3. +func WithAttestationFormats(formats []protocol.AttestationFormat) RegistrationOption { return func(cco *protocol.PublicKeyCredentialCreationOptions) { - cco.Extensions = extension + cco.AttestationFormats = formats } } -// WithCredentialParameters adjusts the credential parameters in the registration options. -func WithCredentialParameters(credentialParams []protocol.CredentialParameter) RegistrationOption { +// WithExtensions adjusts the extension parameter in the registration options. +func WithExtensions(extension protocol.AuthenticationExtensions) RegistrationOption { return func(cco *protocol.PublicKeyCredentialCreationOptions) { - cco.Parameters = credentialParams + cco.Extensions = extension } } @@ -137,7 +185,7 @@ func WithAppIdExcludeExtension(appid string) RegistrationOption { for _, credential := range cco.CredentialExcludeList { if credential.AttestationType == protocol.CredentialTypeFIDOU2F { if cco.Extensions == nil { - cco.Extensions = map[string]interface{}{} + cco.Extensions = map[string]any{} } cco.Extensions[protocol.ExtensionAppIDExclude] = appid @@ -146,17 +194,17 @@ func WithAppIdExcludeExtension(appid string) RegistrationOption { } } -// WithResidentKeyRequirement sets both the resident key and require resident key protocol options. -func WithResidentKeyRequirement(requirement protocol.ResidentKeyRequirement) RegistrationOption { +// WithRegistrationRelyingPartyID sets the relying party id for the registration. +func WithRegistrationRelyingPartyID(id string) RegistrationOption { return func(cco *protocol.PublicKeyCredentialCreationOptions) { - cco.AuthenticatorSelection.ResidentKey = requirement + cco.RelyingParty.ID = id + } +} - switch requirement { - case protocol.ResidentKeyRequirementRequired: - cco.AuthenticatorSelection.RequireResidentKey = protocol.ResidentKeyRequired() - default: - cco.AuthenticatorSelection.RequireResidentKey = protocol.ResidentKeyNotRequired() - } +// WithRegistrationRelyingPartyName sets the relying party name for the registration. +func WithRegistrationRelyingPartyName(name string) RegistrationOption { + return func(cco *protocol.PublicKeyCredentialCreationOptions) { + cco.RelyingParty.Name = name } } @@ -172,7 +220,7 @@ func (webauthn *WebAuthn) FinishRegistration(user User, session SessionData, res } // CreateCredential verifies a parsed response against the user's credentials and session data. -func (webauthn *WebAuthn) CreateCredential(user User, session SessionData, parsedResponse *protocol.ParsedCredentialCreationData) (*Credential, error) { +func (webauthn *WebAuthn) CreateCredential(user User, session SessionData, parsedResponse *protocol.ParsedCredentialCreationData) (credential *Credential, err error) { if !bytes.Equal(user.WebAuthnID(), session.UserID) { return nil, protocol.ErrBadRequest.WithDetails("ID mismatch for User and Session") } @@ -183,15 +231,17 @@ func (webauthn *WebAuthn) CreateCredential(user User, session SessionData, parse shouldVerifyUser := session.UserVerification == protocol.VerificationRequired - invalidErr := parsedResponse.Verify(session.Challenge, shouldVerifyUser, webauthn.Config.RPID, webauthn.Config.RPOrigins) - if invalidErr != nil { - return nil, invalidErr + var clientDataHash []byte + + if clientDataHash, err = parsedResponse.Verify(session.Challenge, shouldVerifyUser, webauthn.Config.RPID, webauthn.Config.RPOrigins, webauthn.Config.RPTopOrigins, webauthn.Config.RPTopOriginVerificationMode, webauthn.Config.MDS); err != nil { + return nil, err } - return MakeNewCredential(parsedResponse) + return NewCredential(clientDataHash, parsedResponse) } -func defaultRegistrationCredentialParameters() []protocol.CredentialParameter { +// CredentialParametersDefault is the default protocol.CredentialParameter list. +func CredentialParametersDefault() []protocol.CredentialParameter { return []protocol.CredentialParameter{ { Type: protocol.PublicKeyCredentialType, @@ -235,3 +285,68 @@ func defaultRegistrationCredentialParameters() []protocol.CredentialParameter { }, } } + +// CredentialParametersRecommendedL3 is explicitly the Level 3 recommended protocol.CredentialParameter list. +func CredentialParametersRecommendedL3() []protocol.CredentialParameter { + return []protocol.CredentialParameter{ + { + Type: protocol.PublicKeyCredentialType, + Algorithm: webauthncose.AlgEdDSA, + }, + { + Type: protocol.PublicKeyCredentialType, + Algorithm: webauthncose.AlgES256, + }, + { + Type: protocol.PublicKeyCredentialType, + Algorithm: webauthncose.AlgRS256, + }, + } +} + +// CredentialParametersExtendedL3 is the Level 3 recommended protocol.CredentialParameter list with all of the other +// parameters supported by the library. +func CredentialParametersExtendedL3() []protocol.CredentialParameter { + return []protocol.CredentialParameter{ + { + Type: protocol.PublicKeyCredentialType, + Algorithm: webauthncose.AlgEdDSA, + }, + { + Type: protocol.PublicKeyCredentialType, + Algorithm: webauthncose.AlgES256, + }, + { + Type: protocol.PublicKeyCredentialType, + Algorithm: webauthncose.AlgES384, + }, + { + Type: protocol.PublicKeyCredentialType, + Algorithm: webauthncose.AlgES512, + }, + { + Type: protocol.PublicKeyCredentialType, + Algorithm: webauthncose.AlgRS256, + }, + { + Type: protocol.PublicKeyCredentialType, + Algorithm: webauthncose.AlgRS384, + }, + { + Type: protocol.PublicKeyCredentialType, + Algorithm: webauthncose.AlgRS512, + }, + { + Type: protocol.PublicKeyCredentialType, + Algorithm: webauthncose.AlgPS256, + }, + { + Type: protocol.PublicKeyCredentialType, + Algorithm: webauthncose.AlgPS384, + }, + { + Type: protocol.PublicKeyCredentialType, + Algorithm: webauthncose.AlgPS512, + }, + } +} diff --git a/vendor/github.com/go-webauthn/webauthn/webauthn/types.go b/vendor/github.com/go-webauthn/webauthn/webauthn/types.go index bb93f31aa4fd597a0eb9a9da4178e682a08cf827..5ce2f93a0db76a6c29cedc756c11133a5dc9f75a 100644 --- a/vendor/github.com/go-webauthn/webauthn/webauthn/types.go +++ b/vendor/github.com/go-webauthn/webauthn/webauthn/types.go @@ -5,6 +5,7 @@ import ( "net/url" "time" + "github.com/go-webauthn/webauthn/metadata" "github.com/go-webauthn/webauthn/protocol" ) @@ -36,6 +37,15 @@ type Config struct { // qualified origins. RPOrigins []string + // RPTopOrigins configures the list of Relying Party Server Top Origins that are permitted. These should be fully + // qualified origins. + RPTopOrigins []string + + // RPTopOriginVerificationMode determines the verification mode for the Top Origin value. By default the + // TopOriginIgnoreVerificationMode is used however this is going to change at such a time as WebAuthn Level 3 + // becomes recommended, implementers should explicitly set this value if they want stability. + RPTopOriginVerificationMode protocol.TopOriginVerificationMode + // AttestationPreference sets the default attestation conveyance preferences. AttestationPreference protocol.ConveyancePreference @@ -53,22 +63,10 @@ type Config struct { // Timeouts configures various timeouts. Timeouts TimeoutsConfig - validated bool - - // RPIcon sets the icon URL for the Relying Party Server. - // - // Deprecated: this option has been removed from newer specifications due to security considerations. - RPIcon string - - // RPOrigin configures the permitted Relying Party Server Origin. - // - // Deprecated: Use RPOrigins instead. - RPOrigin string + // MDS is a metadata.Provider and enables various metadata validations if configured. + MDS metadata.Provider - // Timeout configures the default timeout in milliseconds. - // - // Deprecated: Use Timeouts instead. - Timeout int + validated bool } // TimeoutsConfig represents the WebAuthn timeouts configuration. @@ -97,34 +95,17 @@ func (config *Config) validate() error { return nil } - if len(config.RPDisplayName) == 0 { - return fmt.Errorf(errFmtFieldEmpty, "RPDisplayName") - } - - if len(config.RPID) == 0 { - return fmt.Errorf(errFmtFieldEmpty, "RPID") - } - var err error - if _, err = url.Parse(config.RPID); err != nil { - return fmt.Errorf(errFmtFieldNotValidURI, "RPID", err) - } - - if config.RPIcon != "" { - if _, err = url.Parse(config.RPIcon); err != nil { - return fmt.Errorf(errFmtFieldNotValidURI, "RPIcon", err) + if len(config.RPID) != 0 { + if _, err = url.Parse(config.RPID); err != nil { + return fmt.Errorf(errFmtFieldNotValidURI, "RPID", err) } } defaultTimeoutConfig := defaultTimeout defaultTimeoutUVDConfig := defaultTimeoutUVD - if config.Timeout != 0 { - defaultTimeoutConfig = time.Millisecond * time.Duration(config.Timeout) - defaultTimeoutUVDConfig = defaultTimeoutConfig - } - if config.Timeouts.Login.Timeout.Milliseconds() == 0 { config.Timeouts.Login.Timeout = defaultTimeoutConfig } @@ -141,24 +122,17 @@ func (config *Config) validate() error { config.Timeouts.Registration.TimeoutUVD = defaultTimeoutUVDConfig } - if len(config.RPOrigin) > 0 { - if len(config.RPOrigins) != 0 { - return fmt.Errorf("deprecated field 'RPOrigin' can't be defined at the same tme as the replacement field 'RPOrigins'") - } - - config.RPOrigins = []string{config.RPOrigin} - } - if len(config.RPOrigins) == 0 { return fmt.Errorf("must provide at least one value to the 'RPOrigins' field") } - if config.AuthenticatorSelection.RequireResidentKey == nil { - config.AuthenticatorSelection.RequireResidentKey = protocol.ResidentKeyNotRequired() - } - - if config.AuthenticatorSelection.UserVerification == "" { - config.AuthenticatorSelection.UserVerification = protocol.VerificationPreferred + switch config.RPTopOriginVerificationMode { + case protocol.TopOriginDefaultVerificationMode: + config.RPTopOriginVerificationMode = protocol.TopOriginIgnoreVerificationMode + case protocol.TopOriginImplicitVerificationMode: + if len(config.RPTopOrigins) == 0 { + return fmt.Errorf("must provide at least one value to the 'RPTopOrigins' field when 'RPTopOriginVerificationMode' field is set to protocol.TopOriginImplicitVerificationMode") + } } config.validated = true @@ -166,6 +140,34 @@ func (config *Config) validate() error { return nil } +func (c *Config) GetRPID() string { + return c.RPID +} + +func (c *Config) GetOrigins() []string { + return c.RPOrigins +} + +func (c *Config) GetTopOrigins() []string { + return c.RPTopOrigins +} + +func (c *Config) GetTopOriginVerificationMode() protocol.TopOriginVerificationMode { + return c.RPTopOriginVerificationMode +} + +func (c *Config) GetMetaDataProvider() metadata.Provider { + return c.MDS +} + +type ConfigProvider interface { + GetRPID() string + GetOrigins() []string + GetTopOrigins() []string + GetTopOriginVerificationMode() protocol.TopOriginVerificationMode + GetMetaDataProvider() metadata.Provider +} + // User is an interface with the Relying Party's User entry and provides the fields and methods needed for WebAuthn // registration operations. type User interface { @@ -196,16 +198,13 @@ type User interface { // WebAuthnCredentials provides the list of Credential objects owned by the user. WebAuthnCredentials() []Credential - - // WebAuthnIcon is a deprecated option. - // Deprecated: this has been removed from the specification recommendation. Suggest a blank string. - WebAuthnIcon() string } // SessionData is the data that should be stored by the Relying Party for the duration of the web authentication // ceremony. type SessionData struct { Challenge string `json:"challenge"` + RelyingPartyID string `json:"rpId"` UserID []byte `json:"user_id"` AllowedCredentialIDs [][]byte `json:"allowed_credentials,omitempty"` Expires time.Time `json:"expires"` diff --git a/vendor/github.com/go-webauthn/webauthn/webauthn/user.go b/vendor/github.com/go-webauthn/webauthn/webauthn/user.go deleted file mode 100644 index 045ed8f6b3a54dd5c2118b918534657a05b37f08..0000000000000000000000000000000000000000 --- a/vendor/github.com/go-webauthn/webauthn/webauthn/user.go +++ /dev/null @@ -1,28 +0,0 @@ -package webauthn - -// TODO: move this to a _test.go file. -type defaultUser struct { - id []byte -} - -var _ User = (*defaultUser)(nil) - -func (user *defaultUser) WebAuthnID() []byte { - return user.id -} - -func (user *defaultUser) WebAuthnName() string { - return "newUser" -} - -func (user *defaultUser) WebAuthnDisplayName() string { - return "New User" -} - -func (user *defaultUser) WebAuthnIcon() string { - return "https://pics.com/avatar.png" -} - -func (user *defaultUser) WebAuthnCredentials() []Credential { - return []Credential{} -} diff --git a/vendor/github.com/google/go-tpm/legacy/tpm2/tpm2.go b/vendor/github.com/google/go-tpm/legacy/tpm2/tpm2.go index 8de0c40d520755ce812e157f384351c075daae3b..18d5a960331ce453d7b9c9baa34b73f05b762727 100644 --- a/vendor/github.com/google/go-tpm/legacy/tpm2/tpm2.go +++ b/vendor/github.com/google/go-tpm/legacy/tpm2/tpm2.go @@ -1276,7 +1276,6 @@ func NVDefineSpace(rw io.ReadWriter, owner, handle tpmutil.Handle, ownerAuth, au Auth: []byte(ownerAuth), } return NVDefineSpaceEx(rw, owner, authString, nvPub, authArea) - } // NVDefineSpaceEx accepts NVPublic structure and AuthCommand, allowing more flexibility. @@ -2121,12 +2120,12 @@ func RSAEncrypt(rw io.ReadWriter, key tpmutil.Handle, message []byte, scheme *As return decodeRSAEncrypt(resp) } -func encodeRSADecrypt(key tpmutil.Handle, password string, message tpmutil.U16Bytes, scheme *AsymScheme, label string) ([]byte, error) { +func encodeRSADecrypt(sessionHandle, key tpmutil.Handle, password string, message tpmutil.U16Bytes, scheme *AsymScheme, label string) ([]byte, error) { ha, err := tpmutil.Pack(key) if err != nil { return nil, err } - auth, err := encodeAuthArea(AuthCommand{Session: HandlePasswordSession, Attributes: AttrContinueSession, Auth: []byte(password)}) + auth, err := encodeAuthArea(AuthCommand{Session: sessionHandle, Attributes: AttrContinueSession, Auth: []byte(password)}) if err != nil { return nil, err } @@ -2160,7 +2159,15 @@ func decodeRSADecrypt(resp []byte) ([]byte, error) { // label, a null byte is appended to the label and the null byte is included in the // padding scheme. func RSADecrypt(rw io.ReadWriter, key tpmutil.Handle, password string, message []byte, scheme *AsymScheme, label string) ([]byte, error) { - Cmd, err := encodeRSADecrypt(key, password, message, scheme, label) + return RSADecryptWithSession(rw, HandlePasswordSession, key, password, message, scheme, label) +} + +// RSADecryptWithSession performs RSA decryption in the TPM according to RFC 3447. The key must be +// a private RSA key in the TPM with FlagDecrypt set. Note that when using OAEP with a +// label, a null byte is appended to the label and the null byte is included in the +// padding scheme. +func RSADecryptWithSession(rw io.ReadWriter, sessionHandle, key tpmutil.Handle, password string, message []byte, scheme *AsymScheme, label string) ([]byte, error) { + Cmd, err := encodeRSADecrypt(sessionHandle, key, password, message, scheme, label) if err != nil { return nil, err } diff --git a/vendor/golang.org/x/crypto/ed25519/ed25519.go b/vendor/golang.org/x/crypto/ed25519/ed25519.go deleted file mode 100644 index 59b3a95a7d20fa0fdb40c0686679e82f9d3e25e8..0000000000000000000000000000000000000000 --- a/vendor/golang.org/x/crypto/ed25519/ed25519.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package ed25519 implements the Ed25519 signature algorithm. See -// https://ed25519.cr.yp.to/. -// -// These functions are also compatible with the “Ed25519” function defined in -// RFC 8032. However, unlike RFC 8032's formulation, this package's private key -// representation includes a public key suffix to make multiple signing -// operations with the same key more efficient. This package refers to the RFC -// 8032 private key as the “seed”. -// -// This package is a wrapper around the standard library crypto/ed25519 package. -package ed25519 - -import ( - "crypto/ed25519" - "io" -) - -const ( - // PublicKeySize is the size, in bytes, of public keys as used in this package. - PublicKeySize = 32 - // PrivateKeySize is the size, in bytes, of private keys as used in this package. - PrivateKeySize = 64 - // SignatureSize is the size, in bytes, of signatures generated and verified by this package. - SignatureSize = 64 - // SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032. - SeedSize = 32 -) - -// PublicKey is the type of Ed25519 public keys. -// -// This type is an alias for crypto/ed25519's PublicKey type. -// See the crypto/ed25519 package for the methods on this type. -type PublicKey = ed25519.PublicKey - -// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer. -// -// This type is an alias for crypto/ed25519's PrivateKey type. -// See the crypto/ed25519 package for the methods on this type. -type PrivateKey = ed25519.PrivateKey - -// GenerateKey generates a public/private key pair using entropy from rand. -// If rand is nil, crypto/rand.Reader will be used. -func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) { - return ed25519.GenerateKey(rand) -} - -// NewKeyFromSeed calculates a private key from a seed. It will panic if -// len(seed) is not SeedSize. This function is provided for interoperability -// with RFC 8032. RFC 8032's private keys correspond to seeds in this -// package. -func NewKeyFromSeed(seed []byte) PrivateKey { - return ed25519.NewKeyFromSeed(seed) -} - -// Sign signs the message with privateKey and returns a signature. It will -// panic if len(privateKey) is not PrivateKeySize. -func Sign(privateKey PrivateKey, message []byte) []byte { - return ed25519.Sign(privateKey, message) -} - -// Verify reports whether sig is a valid signature of message by publicKey. It -// will panic if len(publicKey) is not PublicKeySize. -func Verify(publicKey PublicKey, message, sig []byte) bool { - return ed25519.Verify(publicKey, message, sig) -} diff --git a/vendor/golang.org/x/sys/cpu/asm_darwin_x86_gc.s b/vendor/golang.org/x/sys/cpu/asm_darwin_x86_gc.s new file mode 100644 index 0000000000000000000000000000000000000000..ec2acfe540ea7b0e714e137a72f75db190cf8998 --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/asm_darwin_x86_gc.s @@ -0,0 +1,17 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build darwin && amd64 && gc + +#include "textflag.h" + +TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_sysctl(SB) +GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 +DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) + +TEXT libc_sysctlbyname_trampoline<>(SB),NOSPLIT,$0-0 + JMP libc_sysctlbyname(SB) +GLOBL ·libc_sysctlbyname_trampoline_addr(SB), RODATA, $8 +DATA ·libc_sysctlbyname_trampoline_addr(SB)/8, $libc_sysctlbyname_trampoline<>(SB) diff --git a/vendor/golang.org/x/sys/cpu/cpu.go b/vendor/golang.org/x/sys/cpu/cpu.go index 02609d5b21d56a5b82ce169a3bd1f933f9d091f3..9c105f23afcdc411cd3b0368f1077943e91bff45 100644 --- a/vendor/golang.org/x/sys/cpu/cpu.go +++ b/vendor/golang.org/x/sys/cpu/cpu.go @@ -72,6 +72,9 @@ var X86 struct { HasSSSE3 bool // Supplemental streaming SIMD extension 3 HasSSE41 bool // Streaming SIMD extension 4 and 4.1 HasSSE42 bool // Streaming SIMD extension 4 and 4.2 + HasAVXIFMA bool // Advanced vector extension Integer Fused Multiply Add + HasAVXVNNI bool // Advanced vector extension Vector Neural Network Instructions + HasAVXVNNIInt8 bool // Advanced vector extension Vector Neural Network Int8 instructions _ CacheLinePad } diff --git a/vendor/golang.org/x/sys/cpu/cpu_darwin_x86.go b/vendor/golang.org/x/sys/cpu/cpu_darwin_x86.go new file mode 100644 index 0000000000000000000000000000000000000000..b838cb9e956e61f625d7976f3a123f44072e529b --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_darwin_x86.go @@ -0,0 +1,61 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build darwin && amd64 && gc + +package cpu + +// darwinSupportsAVX512 checks Darwin kernel for AVX512 support via sysctl +// call (see issue 43089). It also restricts AVX512 support for Darwin to +// kernel version 21.3.0 (MacOS 12.2.0) or later (see issue 49233). +// +// Background: +// Darwin implements a special mechanism to economize on thread state when +// AVX512 specific registers are not in use. This scheme minimizes state when +// preempting threads that haven't yet used any AVX512 instructions, but adds +// special requirements to check for AVX512 hardware support at runtime (e.g. +// via sysctl call or commpage inspection). See issue 43089 and link below for +// full background: +// https://github.com/apple-oss-distributions/xnu/blob/xnu-11215.1.10/osfmk/i386/fpu.c#L214-L240 +// +// Additionally, all versions of the Darwin kernel from 19.6.0 through 21.2.0 +// (corresponding to MacOS 10.15.6 - 12.1) have a bug that can cause corruption +// of the AVX512 mask registers (K0-K7) upon signal return. For this reason +// AVX512 is considered unsafe to use on Darwin for kernel versions prior to +// 21.3.0, where a fix has been confirmed. See issue 49233 for full background. +func darwinSupportsAVX512() bool { + return darwinSysctlEnabled([]byte("hw.optional.avx512f\x00")) && darwinKernelVersionCheck(21, 3, 0) +} + +// Ensure Darwin kernel version is at least major.minor.patch, avoiding dependencies +func darwinKernelVersionCheck(major, minor, patch int) bool { + var release [256]byte + err := darwinOSRelease(&release) + if err != nil { + return false + } + + var mmp [3]int + c := 0 +Loop: + for _, b := range release[:] { + switch { + case b >= '0' && b <= '9': + mmp[c] = 10*mmp[c] + int(b-'0') + case b == '.': + c++ + if c > 2 { + return false + } + case b == 0: + break Loop + default: + return false + } + } + if c != 2 { + return false + } + return mmp[0] > major || mmp[0] == major && (mmp[1] > minor || mmp[1] == minor && mmp[2] >= patch) +} diff --git a/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go b/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go index 910728fb163f36695c04e99064c4e5adf09a160c..32a44514e245fe38568a04ce77817b1b8c01aa73 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go +++ b/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go @@ -6,10 +6,10 @@ package cpu -// cpuid is implemented in cpu_x86.s for gc compiler +// cpuid is implemented in cpu_gc_x86.s for gc compiler // and in cpu_gccgo.c for gccgo. func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) -// xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler +// xgetbv with ecx = 0 is implemented in cpu_gc_x86.s for gc compiler // and in cpu_gccgo.c for gccgo. func xgetbv() (eax, edx uint32) diff --git a/vendor/golang.org/x/sys/cpu/cpu_x86.s b/vendor/golang.org/x/sys/cpu/cpu_gc_x86.s similarity index 94% rename from vendor/golang.org/x/sys/cpu/cpu_x86.s rename to vendor/golang.org/x/sys/cpu/cpu_gc_x86.s index 7d7ba33efb85559b3dded691773f12342163fdd6..ce208ce6d6a3a64925076de5b9db96a4afedaf0d 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_x86.s +++ b/vendor/golang.org/x/sys/cpu/cpu_gc_x86.s @@ -18,7 +18,7 @@ TEXT ·cpuid(SB), NOSPLIT, $0-24 RET // func xgetbv() (eax, edx uint32) -TEXT ·xgetbv(SB),NOSPLIT,$0-8 +TEXT ·xgetbv(SB), NOSPLIT, $0-8 MOVL $0, CX XGETBV MOVL AX, eax+0(FP) diff --git a/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go b/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go index 99c60fe9f9c657795eaaf6cf85863114f58bb191..170d21ddfda4163fb6d9d2094fb62ff9e027fb65 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go +++ b/vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go @@ -23,9 +23,3 @@ func xgetbv() (eax, edx uint32) { gccgoXgetbv(&a, &d) return a, d } - -// gccgo doesn't build on Darwin, per: -// https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/gcc.rb#L76 -func darwinSupportsAVX512() bool { - return false -} diff --git a/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go b/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go index 08f35ea17735fddf8125d17ffeecbcb5dc6debb2..f1caf0f78e24b65db57f1b599d8bead8e1d9d65f 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go @@ -110,7 +110,6 @@ func doinit() { ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM) ARM64.HasDIT = isSet(hwCap, hwcap_DIT) - // HWCAP2 feature bits ARM64.HasSVE2 = isSet(hwCap2, hwcap2_SVE2) ARM64.HasI8MM = isSet(hwCap2, hwcap2_I8MM) diff --git a/vendor/golang.org/x/sys/cpu/cpu_other_x86.go b/vendor/golang.org/x/sys/cpu/cpu_other_x86.go new file mode 100644 index 0000000000000000000000000000000000000000..a0fd7e2f75d37fe6f894f799caae51d9b6fe006f --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/cpu_other_x86.go @@ -0,0 +1,11 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build 386 || amd64p32 || (amd64 && (!darwin || !gc)) + +package cpu + +func darwinSupportsAVX512() bool { + panic("only implemented for gc && amd64 && darwin") +} diff --git a/vendor/golang.org/x/sys/cpu/cpu_x86.go b/vendor/golang.org/x/sys/cpu/cpu_x86.go index c29f5e4c5a6e4ef36f32964e99910cb710205f97..1e642f3304fa87b95c67d47454e2eb62825fccf2 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_x86.go +++ b/vendor/golang.org/x/sys/cpu/cpu_x86.go @@ -53,6 +53,9 @@ func initOptions() { {Name: "sse41", Feature: &X86.HasSSE41}, {Name: "sse42", Feature: &X86.HasSSE42}, {Name: "ssse3", Feature: &X86.HasSSSE3}, + {Name: "avxifma", Feature: &X86.HasAVXIFMA}, + {Name: "avxvnni", Feature: &X86.HasAVXVNNI}, + {Name: "avxvnniint8", Feature: &X86.HasAVXVNNIInt8}, // These capabilities should always be enabled on amd64: {Name: "sse2", Feature: &X86.HasSSE2, Required: runtime.GOARCH == "amd64"}, @@ -92,10 +95,8 @@ func archInit() { osSupportsAVX = isSet(1, eax) && isSet(2, eax) if runtime.GOOS == "darwin" { - // Darwin doesn't save/restore AVX-512 mask registers correctly across signal handlers. - // Since users can't rely on mask register contents, let's not advertise AVX-512 support. - // See issue 49233. - osSupportsAVX512 = false + // Darwin requires special AVX512 checks, see cpu_darwin_x86.go + osSupportsAVX512 = osSupportsAVX && darwinSupportsAVX512() } else { // Check if OPMASK and ZMM registers have OS support. osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax) @@ -108,7 +109,7 @@ func archInit() { return } - _, ebx7, ecx7, edx7 := cpuid(7, 0) + eax7, ebx7, ecx7, edx7 := cpuid(7, 0) X86.HasBMI1 = isSet(3, ebx7) X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX X86.HasBMI2 = isSet(8, ebx7) @@ -136,14 +137,24 @@ func archInit() { X86.HasAVX512VAES = isSet(9, ecx7) X86.HasAVX512VBMI2 = isSet(6, ecx7) X86.HasAVX512BITALG = isSet(12, ecx7) - - eax71, _, _, _ := cpuid(7, 1) - X86.HasAVX512BF16 = isSet(5, eax71) } X86.HasAMXTile = isSet(24, edx7) X86.HasAMXInt8 = isSet(25, edx7) X86.HasAMXBF16 = isSet(22, edx7) + + // These features depend on the second level of extended features. + if eax7 >= 1 { + eax71, _, _, edx71 := cpuid(7, 1) + if X86.HasAVX512 { + X86.HasAVX512BF16 = isSet(5, eax71) + } + if X86.HasAVX { + X86.HasAVXIFMA = isSet(23, eax71) + X86.HasAVXVNNI = isSet(4, eax71) + X86.HasAVXVNNIInt8 = isSet(4, edx71) + } + } } func isSet(bitpos uint, value uint32) bool { diff --git a/vendor/golang.org/x/sys/cpu/syscall_darwin_x86_gc.go b/vendor/golang.org/x/sys/cpu/syscall_darwin_x86_gc.go new file mode 100644 index 0000000000000000000000000000000000000000..4d0888b0c010f41faaf56692175b7d395bb7494a --- /dev/null +++ b/vendor/golang.org/x/sys/cpu/syscall_darwin_x86_gc.go @@ -0,0 +1,98 @@ +// Copyright 2024 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. + +// Minimal copy of x/sys/unix so the cpu package can make a +// system call on Darwin without depending on x/sys/unix. + +//go:build darwin && amd64 && gc + +package cpu + +import ( + "syscall" + "unsafe" +) + +type _C_int int32 + +// adapted from unix.Uname() at x/sys/unix/syscall_darwin.go L419 +func darwinOSRelease(release *[256]byte) error { + // from x/sys/unix/zerrors_openbsd_amd64.go + const ( + CTL_KERN = 0x1 + KERN_OSRELEASE = 0x2 + ) + + mib := []_C_int{CTL_KERN, KERN_OSRELEASE} + n := unsafe.Sizeof(*release) + + return sysctl(mib, &release[0], &n, nil, 0) +} + +type Errno = syscall.Errno + +var _zero uintptr // Single-word zero for use when we need a valid pointer to 0 bytes. + +// from x/sys/unix/zsyscall_darwin_amd64.go L791-807 +func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) error { + var _p0 unsafe.Pointer + if len(mib) > 0 { + _p0 = unsafe.Pointer(&mib[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + if _, _, err := syscall_syscall6( + libc_sysctl_trampoline_addr, + uintptr(_p0), + uintptr(len(mib)), + uintptr(unsafe.Pointer(old)), + uintptr(unsafe.Pointer(oldlen)), + uintptr(unsafe.Pointer(new)), + uintptr(newlen), + ); err != 0 { + return err + } + + return nil +} + +var libc_sysctl_trampoline_addr uintptr + +// adapted from internal/cpu/cpu_arm64_darwin.go +func darwinSysctlEnabled(name []byte) bool { + out := int32(0) + nout := unsafe.Sizeof(out) + if ret := sysctlbyname(&name[0], (*byte)(unsafe.Pointer(&out)), &nout, nil, 0); ret != nil { + return false + } + return out > 0 +} + +//go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib" + +var libc_sysctlbyname_trampoline_addr uintptr + +// adapted from runtime/sys_darwin.go in the pattern of sysctl() above, as defined in x/sys/unix +func sysctlbyname(name *byte, old *byte, oldlen *uintptr, new *byte, newlen uintptr) error { + if _, _, err := syscall_syscall6( + libc_sysctlbyname_trampoline_addr, + uintptr(unsafe.Pointer(name)), + uintptr(unsafe.Pointer(old)), + uintptr(unsafe.Pointer(oldlen)), + uintptr(unsafe.Pointer(new)), + uintptr(newlen), + 0, + ); err != 0 { + return err + } + + return nil +} + +//go:cgo_import_dynamic libc_sysctlbyname sysctlbyname "/usr/lib/libSystem.B.dylib" + +// Implemented in the runtime package (runtime/sys_darwin.go) +func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) + +//go:linkname syscall_syscall6 syscall.syscall6 diff --git a/vendor/golang.org/x/sys/unix/README.md b/vendor/golang.org/x/sys/unix/README.md index 7d3c060e12213c48b017dfd2846fb9b1cf413d31..6e08a76a716e9acd766c9cda4ea56d607b481470 100644 --- a/vendor/golang.org/x/sys/unix/README.md +++ b/vendor/golang.org/x/sys/unix/README.md @@ -156,7 +156,7 @@ from the generated architecture-specific files listed below, and merge these into a common file for each OS. The merge is performed in the following steps: -1. Construct the set of common code that is idential in all architecture-specific files. +1. Construct the set of common code that is identical in all architecture-specific files. 2. Write this common code to the merged file. 3. Remove the common code from all architecture-specific files. diff --git a/vendor/golang.org/x/sys/unix/auxv.go b/vendor/golang.org/x/sys/unix/auxv.go new file mode 100644 index 0000000000000000000000000000000000000000..37a82528f580f1a3fa7ed57d65cbb8ee7097a98e --- /dev/null +++ b/vendor/golang.org/x/sys/unix/auxv.go @@ -0,0 +1,36 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) + +package unix + +import ( + "syscall" + "unsafe" +) + +//go:linkname runtime_getAuxv runtime.getAuxv +func runtime_getAuxv() []uintptr + +// Auxv returns the ELF auxiliary vector as a sequence of key/value pairs. +// The returned slice is always a fresh copy, owned by the caller. +// It returns an error on non-ELF platforms, or if the auxiliary vector cannot be accessed, +// which happens in some locked-down environments and build modes. +func Auxv() ([][2]uintptr, error) { + vec := runtime_getAuxv() + vecLen := len(vec) + + if vecLen == 0 { + return nil, syscall.ENOENT + } + + if vecLen%2 != 0 { + return nil, syscall.EINVAL + } + + result := make([]uintptr, vecLen) + copy(result, vec) + return unsafe.Slice((*[2]uintptr)(unsafe.Pointer(&result[0])), vecLen/2), nil +} diff --git a/vendor/golang.org/x/sys/unix/auxv_unsupported.go b/vendor/golang.org/x/sys/unix/auxv_unsupported.go new file mode 100644 index 0000000000000000000000000000000000000000..1200487f2e86c60b112d6042f329ce48f677bb64 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/auxv_unsupported.go @@ -0,0 +1,13 @@ +// Copyright 2025 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) + +package unix + +import "syscall" + +func Auxv() ([][2]uintptr, error) { + return nil, syscall.ENOTSUP +} diff --git a/vendor/golang.org/x/sys/unix/ioctl_linux.go b/vendor/golang.org/x/sys/unix/ioctl_linux.go index dbe680eab88a9e281759b0b9db9cf1ff708b31d8..7ca4fa12aa673c6bbdaaac287ea68eb43408ff03 100644 --- a/vendor/golang.org/x/sys/unix/ioctl_linux.go +++ b/vendor/golang.org/x/sys/unix/ioctl_linux.go @@ -58,6 +58,102 @@ func IoctlGetEthtoolDrvinfo(fd int, ifname string) (*EthtoolDrvinfo, error) { return &value, err } +// IoctlGetEthtoolTsInfo fetches ethtool timestamping and PHC +// association for the network device specified by ifname. +func IoctlGetEthtoolTsInfo(fd int, ifname string) (*EthtoolTsInfo, error) { + ifr, err := NewIfreq(ifname) + if err != nil { + return nil, err + } + + value := EthtoolTsInfo{Cmd: ETHTOOL_GET_TS_INFO} + ifrd := ifr.withData(unsafe.Pointer(&value)) + + err = ioctlIfreqData(fd, SIOCETHTOOL, &ifrd) + return &value, err +} + +// IoctlGetHwTstamp retrieves the hardware timestamping configuration +// for the network device specified by ifname. +func IoctlGetHwTstamp(fd int, ifname string) (*HwTstampConfig, error) { + ifr, err := NewIfreq(ifname) + if err != nil { + return nil, err + } + + value := HwTstampConfig{} + ifrd := ifr.withData(unsafe.Pointer(&value)) + + err = ioctlIfreqData(fd, SIOCGHWTSTAMP, &ifrd) + return &value, err +} + +// IoctlSetHwTstamp updates the hardware timestamping configuration for +// the network device specified by ifname. +func IoctlSetHwTstamp(fd int, ifname string, cfg *HwTstampConfig) error { + ifr, err := NewIfreq(ifname) + if err != nil { + return err + } + ifrd := ifr.withData(unsafe.Pointer(cfg)) + return ioctlIfreqData(fd, SIOCSHWTSTAMP, &ifrd) +} + +// FdToClockID derives the clock ID from the file descriptor number +// - see clock_gettime(3), FD_TO_CLOCKID macros. The resulting ID is +// suitable for system calls like ClockGettime. +func FdToClockID(fd int) int32 { return int32((int(^fd) << 3) | 3) } + +// IoctlPtpClockGetcaps returns the description of a given PTP device. +func IoctlPtpClockGetcaps(fd int) (*PtpClockCaps, error) { + var value PtpClockCaps + err := ioctlPtr(fd, PTP_CLOCK_GETCAPS2, unsafe.Pointer(&value)) + return &value, err +} + +// IoctlPtpSysOffsetPrecise returns a description of the clock +// offset compared to the system clock. +func IoctlPtpSysOffsetPrecise(fd int) (*PtpSysOffsetPrecise, error) { + var value PtpSysOffsetPrecise + err := ioctlPtr(fd, PTP_SYS_OFFSET_PRECISE2, unsafe.Pointer(&value)) + return &value, err +} + +// IoctlPtpSysOffsetExtended returns an extended description of the +// clock offset compared to the system clock. The samples parameter +// specifies the desired number of measurements. +func IoctlPtpSysOffsetExtended(fd int, samples uint) (*PtpSysOffsetExtended, error) { + value := PtpSysOffsetExtended{Samples: uint32(samples)} + err := ioctlPtr(fd, PTP_SYS_OFFSET_EXTENDED2, unsafe.Pointer(&value)) + return &value, err +} + +// IoctlPtpPinGetfunc returns the configuration of the specified +// I/O pin on given PTP device. +func IoctlPtpPinGetfunc(fd int, index uint) (*PtpPinDesc, error) { + value := PtpPinDesc{Index: uint32(index)} + err := ioctlPtr(fd, PTP_PIN_GETFUNC2, unsafe.Pointer(&value)) + return &value, err +} + +// IoctlPtpPinSetfunc updates configuration of the specified PTP +// I/O pin. +func IoctlPtpPinSetfunc(fd int, pd *PtpPinDesc) error { + return ioctlPtr(fd, PTP_PIN_SETFUNC2, unsafe.Pointer(pd)) +} + +// IoctlPtpPeroutRequest configures the periodic output mode of the +// PTP I/O pins. +func IoctlPtpPeroutRequest(fd int, r *PtpPeroutRequest) error { + return ioctlPtr(fd, PTP_PEROUT_REQUEST2, unsafe.Pointer(r)) +} + +// IoctlPtpExttsRequest configures the external timestamping mode +// of the PTP I/O pins. +func IoctlPtpExttsRequest(fd int, r *PtpExttsRequest) error { + return ioctlPtr(fd, PTP_EXTTS_REQUEST2, unsafe.Pointer(r)) +} + // IoctlGetWatchdogInfo fetches information about a watchdog device from the // Linux watchdog API. For more information, see: // https://www.kernel.org/doc/html/latest/watchdog/watchdog-api.html. diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index e14b766a32c5fb4b3f85d0ce5a7ddf4fce35b81a..6ab02b6c3122afd5e2ea1a7cf7f31a43342746fb 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -158,6 +158,16 @@ includes_Linux=' #endif #define _GNU_SOURCE +// See the description in unix/linux/types.go +#if defined(__ARM_EABI__) || \ + (defined(__mips__) && (_MIPS_SIM == _ABIO32)) || \ + (defined(__powerpc__) && (!defined(__powerpc64__))) +# ifdef _TIME_BITS +# undef _TIME_BITS +# endif +# define _TIME_BITS 32 +#endif + // <sys/ioctl.h> is broken on powerpc64, as it fails to include definitions of // these structures. We just include them copied from <bits/termios.h>. #if defined(__powerpc__) @@ -256,6 +266,7 @@ struct ltchars { #include <linux/nsfs.h> #include <linux/perf_event.h> #include <linux/pps.h> +#include <linux/ptp_clock.h> #include <linux/ptrace.h> #include <linux/random.h> #include <linux/reboot.h> @@ -527,6 +538,7 @@ ccflags="$@" $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ || $2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ || $2 ~ /^NFC_.*_(MAX)?SIZE$/ || + $2 ~ /^PTP_/ || $2 ~ /^RAW_PAYLOAD_/ || $2 ~ /^[US]F_/ || $2 ~ /^TP_STATUS_/ || @@ -656,7 +668,7 @@ errors=$( signals=$( echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags | awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' | - grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' | + grep -E -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' | sort ) @@ -666,7 +678,7 @@ echo '#include <errno.h>' | $CC -x c - -E -dM $ccflags | sort >_error.grep echo '#include <signal.h>' | $CC -x c - -E -dM $ccflags | awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }' | - grep -v 'SIGSTKSIZE\|SIGSTKSZ\|SIGRT\|SIGMAX64' | + grep -E -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT|SIGMAX64)' | sort >_signal.grep echo '// mkerrors.sh' "$@" diff --git a/vendor/golang.org/x/sys/unix/syscall_aix.go b/vendor/golang.org/x/sys/unix/syscall_aix.go index 67ce6cef2d5c4990629b90eb43d888b90612d671..6f15ba1eaff6571878742b4d058e084f30afa6f2 100644 --- a/vendor/golang.org/x/sys/unix/syscall_aix.go +++ b/vendor/golang.org/x/sys/unix/syscall_aix.go @@ -360,7 +360,7 @@ func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, var status _C_int var r Pid_t err = ERESTART - // AIX wait4 may return with ERESTART errno, while the processus is still + // AIX wait4 may return with ERESTART errno, while the process is still // active. for err == ERESTART { r, err = wait4(Pid_t(pid), &status, options, rusage) diff --git a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go index 97cb916f2c90ef178ea7d14f319ff73360ef2210..be8c0020701ee4ccbc415fb16e00108033093c5b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go +++ b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go @@ -246,6 +246,18 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e return sendfile(outfd, infd, offset, count) } +func Dup3(oldfd, newfd, flags int) error { + if oldfd == newfd || flags&^O_CLOEXEC != 0 { + return EINVAL + } + how := F_DUP2FD + if flags&O_CLOEXEC != 0 { + how = F_DUP2FD_CLOEXEC + } + _, err := fcntl(oldfd, how, newfd) + return err +} + /* * Exposed directly */ diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 3f1d3d4cb2560b171bd7414fb6cbe6abcac17df6..230a94549a7a278527848109714e2e3285888732 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -1295,6 +1295,48 @@ func GetsockoptTCPInfo(fd, level, opt int) (*TCPInfo, error) { return &value, err } +// GetsockoptTCPCCVegasInfo returns algorithm specific congestion control information for a socket using the "vegas" +// algorithm. +// +// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option: +// +// algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION) +func GetsockoptTCPCCVegasInfo(fd, level, opt int) (*TCPVegasInfo, error) { + var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment + vallen := _Socklen(SizeofTCPCCInfo) + err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) + out := (*TCPVegasInfo)(unsafe.Pointer(&value[0])) + return out, err +} + +// GetsockoptTCPCCDCTCPInfo returns algorithm specific congestion control information for a socket using the "dctp" +// algorithm. +// +// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option: +// +// algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION) +func GetsockoptTCPCCDCTCPInfo(fd, level, opt int) (*TCPDCTCPInfo, error) { + var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment + vallen := _Socklen(SizeofTCPCCInfo) + err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) + out := (*TCPDCTCPInfo)(unsafe.Pointer(&value[0])) + return out, err +} + +// GetsockoptTCPCCBBRInfo returns algorithm specific congestion control information for a socket using the "bbr" +// algorithm. +// +// The socket's congestion control algorighm can be retrieved via [GetsockoptString] with the [TCP_CONGESTION] option: +// +// algo, err := unix.GetsockoptString(fd, unix.IPPROTO_TCP, unix.TCP_CONGESTION) +func GetsockoptTCPCCBBRInfo(fd, level, opt int) (*TCPBBRInfo, error) { + var value [SizeofTCPCCInfo / 4]uint32 // ensure proper alignment + vallen := _Socklen(SizeofTCPCCInfo) + err := getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen) + out := (*TCPBBRInfo)(unsafe.Pointer(&value[0])) + return out, err +} + // GetsockoptString returns the string value of the socket option opt for the // socket associated with fd at the given socket level. func GetsockoptString(fd, level, opt int) (string, error) { @@ -1818,6 +1860,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys ClockAdjtime(clockid int32, buf *Timex) (state int, err error) //sys ClockGetres(clockid int32, res *Timespec) (err error) //sys ClockGettime(clockid int32, time *Timespec) (err error) +//sys ClockSettime(clockid int32, time *Timespec) (err error) //sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) //sys Close(fd int) (err error) //sys CloseRange(first uint, last uint, flags uint) (err error) @@ -1959,7 +2002,26 @@ func Getpgrp() (pid int) { //sysnb Getpid() (pid int) //sysnb Getppid() (ppid int) //sys Getpriority(which int, who int) (prio int, err error) -//sys Getrandom(buf []byte, flags int) (n int, err error) + +func Getrandom(buf []byte, flags int) (n int, err error) { + vdsoRet, supported := vgetrandom(buf, uint32(flags)) + if supported { + if vdsoRet < 0 { + return 0, errnoErr(syscall.Errno(-vdsoRet)) + } + return vdsoRet, nil + } + var p *byte + if len(buf) > 0 { + p = &buf[0] + } + r, _, e := Syscall(SYS_GETRANDOM, uintptr(unsafe.Pointer(p)), uintptr(len(buf)), uintptr(flags)) + if e != 0 { + return 0, errnoErr(e) + } + return int(r), nil +} + //sysnb Getrusage(who int, rusage *Rusage) (err error) //sysnb Getsid(pid int) (sid int, err error) //sysnb Gettid() (tid int) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go index cf2ee6c75ef3d3905f8a6575b00500bc246d483d..745e5c7e6c0d5d6cde926549e394f8c541e7371b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go @@ -182,3 +182,5 @@ func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error } return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags) } + +const SYS_FSTATAT = SYS_NEWFSTATAT diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go b/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go index 3d0e98451f8a78933ecf08740b1f6e744f0d627a..dd2262a40799a2cdeb02e40a4526aa8b3533c258 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_loong64.go @@ -214,3 +214,5 @@ func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error } return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags) } + +const SYS_FSTATAT = SYS_NEWFSTATAT diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go index 6f5a288944dfe604dd0f33b5b32e5d91b827c3f1..8cf3670bda630e22ea33151e00c3895c72dda69c 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go @@ -187,3 +187,5 @@ func RISCVHWProbe(pairs []RISCVHWProbePairs, set *CPUSet, flags uint) (err error } return riscvHWProbe(pairs, setSize, set, flags) } + +const SYS_FSTATAT = SYS_NEWFSTATAT diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go index 21974af064ddc38e765f3543cda0a9ca29aa44aa..abc3955477c7d38a774bc46bdd8ed0fd736a7bb8 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go @@ -1102,3 +1102,90 @@ func (s *Strioctl) SetInt(i int) { func IoctlSetStrioctlRetInt(fd int, req int, s *Strioctl) (int, error) { return ioctlPtrRet(fd, req, unsafe.Pointer(s)) } + +// Ucred Helpers +// See ucred(3c) and getpeerucred(3c) + +//sys getpeerucred(fd uintptr, ucred *uintptr) (err error) +//sys ucredFree(ucred uintptr) = ucred_free +//sys ucredGet(pid int) (ucred uintptr, err error) = ucred_get +//sys ucredGeteuid(ucred uintptr) (uid int) = ucred_geteuid +//sys ucredGetegid(ucred uintptr) (gid int) = ucred_getegid +//sys ucredGetruid(ucred uintptr) (uid int) = ucred_getruid +//sys ucredGetrgid(ucred uintptr) (gid int) = ucred_getrgid +//sys ucredGetsuid(ucred uintptr) (uid int) = ucred_getsuid +//sys ucredGetsgid(ucred uintptr) (gid int) = ucred_getsgid +//sys ucredGetpid(ucred uintptr) (pid int) = ucred_getpid + +// Ucred is an opaque struct that holds user credentials. +type Ucred struct { + ucred uintptr +} + +// We need to ensure that ucredFree is called on the underlying ucred +// when the Ucred is garbage collected. +func ucredFinalizer(u *Ucred) { + ucredFree(u.ucred) +} + +func GetPeerUcred(fd uintptr) (*Ucred, error) { + var ucred uintptr + err := getpeerucred(fd, &ucred) + if err != nil { + return nil, err + } + result := &Ucred{ + ucred: ucred, + } + // set the finalizer on the result so that the ucred will be freed + runtime.SetFinalizer(result, ucredFinalizer) + return result, nil +} + +func UcredGet(pid int) (*Ucred, error) { + ucred, err := ucredGet(pid) + if err != nil { + return nil, err + } + result := &Ucred{ + ucred: ucred, + } + // set the finalizer on the result so that the ucred will be freed + runtime.SetFinalizer(result, ucredFinalizer) + return result, nil +} + +func (u *Ucred) Geteuid() int { + defer runtime.KeepAlive(u) + return ucredGeteuid(u.ucred) +} + +func (u *Ucred) Getruid() int { + defer runtime.KeepAlive(u) + return ucredGetruid(u.ucred) +} + +func (u *Ucred) Getsuid() int { + defer runtime.KeepAlive(u) + return ucredGetsuid(u.ucred) +} + +func (u *Ucred) Getegid() int { + defer runtime.KeepAlive(u) + return ucredGetegid(u.ucred) +} + +func (u *Ucred) Getrgid() int { + defer runtime.KeepAlive(u) + return ucredGetrgid(u.ucred) +} + +func (u *Ucred) Getsgid() int { + defer runtime.KeepAlive(u) + return ucredGetsgid(u.ucred) +} + +func (u *Ucred) Getpid() int { + defer runtime.KeepAlive(u) + return ucredGetpid(u.ucred) +} diff --git a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go index 312ae6ac1d21abb1b847d1036e21f20d877876b2..7bf5c04bb0ae0d539b6082d0b5d60f3f4202f74a 100644 --- a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go @@ -768,6 +768,15 @@ func Munmap(b []byte) (err error) { return mapper.Munmap(b) } +func MmapPtr(fd int, offset int64, addr unsafe.Pointer, length uintptr, prot int, flags int) (ret unsafe.Pointer, err error) { + xaddr, err := mapper.mmap(uintptr(addr), length, prot, flags, fd, offset) + return unsafe.Pointer(xaddr), err +} + +func MunmapPtr(addr unsafe.Pointer, length uintptr) (err error) { + return mapper.munmap(uintptr(addr), length) +} + //sys Gethostname(buf []byte) (err error) = SYS___GETHOSTNAME_A //sysnb Getgid() (gid int) //sysnb Getpid() (pid int) @@ -816,10 +825,10 @@ func Lstat(path string, stat *Stat_t) (err error) { // for checking symlinks begins with $VERSION/ $SYSNAME/ $SYSSYMR/ $SYSSYMA/ func isSpecialPath(path []byte) (v bool) { var special = [4][8]byte{ - [8]byte{'V', 'E', 'R', 'S', 'I', 'O', 'N', '/'}, - [8]byte{'S', 'Y', 'S', 'N', 'A', 'M', 'E', '/'}, - [8]byte{'S', 'Y', 'S', 'S', 'Y', 'M', 'R', '/'}, - [8]byte{'S', 'Y', 'S', 'S', 'Y', 'M', 'A', '/'}} + {'V', 'E', 'R', 'S', 'I', 'O', 'N', '/'}, + {'S', 'Y', 'S', 'N', 'A', 'M', 'E', '/'}, + {'S', 'Y', 'S', 'S', 'Y', 'M', 'R', '/'}, + {'S', 'Y', 'S', 'S', 'Y', 'M', 'A', '/'}} var i, j int for i = 0; i < len(special); i++ { @@ -3115,3 +3124,90 @@ func legacy_Mkfifoat(dirfd int, path string, mode uint32) (err error) { //sys Posix_openpt(oflag int) (fd int, err error) = SYS_POSIX_OPENPT //sys Grantpt(fildes int) (rc int, err error) = SYS_GRANTPT //sys Unlockpt(fildes int) (rc int, err error) = SYS_UNLOCKPT + +func fcntlAsIs(fd uintptr, cmd int, arg uintptr) (val int, err error) { + runtime.EnterSyscall() + r0, e2, e1 := CallLeFuncWithErr(GetZosLibVec()+SYS_FCNTL<<4, uintptr(fd), uintptr(cmd), arg) + runtime.ExitSyscall() + val = int(r0) + if int64(r0) == -1 { + err = errnoErr2(e1, e2) + } + return +} + +func Fcntl(fd uintptr, cmd int, op interface{}) (ret int, err error) { + switch op.(type) { + case *Flock_t: + err = FcntlFlock(fd, cmd, op.(*Flock_t)) + if err != nil { + ret = -1 + } + return + case int: + return FcntlInt(fd, cmd, op.(int)) + case *F_cnvrt: + return fcntlAsIs(fd, cmd, uintptr(unsafe.Pointer(op.(*F_cnvrt)))) + case unsafe.Pointer: + return fcntlAsIs(fd, cmd, uintptr(op.(unsafe.Pointer))) + default: + return -1, EINVAL + } + return +} + +func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { + if raceenabled { + raceReleaseMerge(unsafe.Pointer(&ioSync)) + } + return sendfile(outfd, infd, offset, count) +} + +func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { + // TODO: use LE call instead if the call is implemented + originalOffset, err := Seek(infd, 0, SEEK_CUR) + if err != nil { + return -1, err + } + //start reading data from in_fd + if offset != nil { + _, err := Seek(infd, *offset, SEEK_SET) + if err != nil { + return -1, err + } + } + + buf := make([]byte, count) + readBuf := make([]byte, 0) + var n int = 0 + for i := 0; i < count; i += n { + n, err := Read(infd, buf) + if n == 0 { + if err != nil { + return -1, err + } else { // EOF + break + } + } + readBuf = append(readBuf, buf...) + buf = buf[0:0] + } + + n2, err := Write(outfd, readBuf) + if err != nil { + return -1, err + } + + //When sendfile() returns, this variable will be set to the + // offset of the byte following the last byte that was read. + if offset != nil { + *offset = *offset + int64(n) + // If offset is not NULL, then sendfile() does not modify the file + // offset of in_fd + _, err := Seek(infd, originalOffset, SEEK_SET) + if err != nil { + return -1, err + } + } + return n2, nil +} diff --git a/vendor/golang.org/x/sys/unix/vgetrandom_linux.go b/vendor/golang.org/x/sys/unix/vgetrandom_linux.go new file mode 100644 index 0000000000000000000000000000000000000000..07ac8e09d1b702b1abd56252d7c6d1135580f559 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/vgetrandom_linux.go @@ -0,0 +1,13 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build linux && go1.24 + +package unix + +import _ "unsafe" + +//go:linkname vgetrandom runtime.vgetrandom +//go:noescape +func vgetrandom(p []byte, flags uint32) (ret int, supported bool) diff --git a/vendor/golang.org/x/sys/unix/vgetrandom_unsupported.go b/vendor/golang.org/x/sys/unix/vgetrandom_unsupported.go new file mode 100644 index 0000000000000000000000000000000000000000..297e97bce92a6ebc7eeebc067685a2587b5f7e63 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/vgetrandom_unsupported.go @@ -0,0 +1,11 @@ +// Copyright 2024 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !linux || !go1.24 + +package unix + +func vgetrandom(p []byte, flags uint32) (ret int, supported bool) { + return -1, false +} diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 01a70b24638e60cde45588ff39ee6bfd1d915a21..4f432bfe8feeee77862ace1bbfbed983d72f6e76 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -321,6 +321,9 @@ const ( AUDIT_INTEGRITY_STATUS = 0x70a AUDIT_IPC = 0x517 AUDIT_IPC_SET_PERM = 0x51f + AUDIT_IPE_ACCESS = 0x58c + AUDIT_IPE_CONFIG_CHANGE = 0x58d + AUDIT_IPE_POLICY_LOAD = 0x58e AUDIT_KERNEL = 0x7d0 AUDIT_KERNEL_OTHER = 0x524 AUDIT_KERN_MODULE = 0x532 @@ -489,12 +492,14 @@ const ( BPF_F_ID = 0x20 BPF_F_NETFILTER_IP_DEFRAG = 0x1 BPF_F_QUERY_EFFECTIVE = 0x1 + BPF_F_REDIRECT_FLAGS = 0x19 BPF_F_REPLACE = 0x4 BPF_F_SLEEPABLE = 0x10 BPF_F_STRICT_ALIGNMENT = 0x1 BPF_F_TEST_REG_INVARIANTS = 0x80 BPF_F_TEST_RND_HI32 = 0x4 BPF_F_TEST_RUN_ON_CPU = 0x1 + BPF_F_TEST_SKB_CHECKSUM_COMPLETE = 0x4 BPF_F_TEST_STATE_FREQ = 0x8 BPF_F_TEST_XDP_LIVE_FRAMES = 0x2 BPF_F_XDP_DEV_BOUND_ONLY = 0x40 @@ -1165,6 +1170,7 @@ const ( EXTA = 0xe EXTB = 0xf F2FS_SUPER_MAGIC = 0xf2f52010 + FALLOC_FL_ALLOCATE_RANGE = 0x0 FALLOC_FL_COLLAPSE_RANGE = 0x8 FALLOC_FL_INSERT_RANGE = 0x20 FALLOC_FL_KEEP_SIZE = 0x1 @@ -1239,6 +1245,7 @@ const ( FAN_REPORT_DFID_NAME = 0xc00 FAN_REPORT_DFID_NAME_TARGET = 0x1e00 FAN_REPORT_DIR_FID = 0x400 + FAN_REPORT_FD_ERROR = 0x2000 FAN_REPORT_FID = 0x200 FAN_REPORT_NAME = 0x800 FAN_REPORT_PIDFD = 0x80 @@ -1324,8 +1331,10 @@ const ( FUSE_SUPER_MAGIC = 0x65735546 FUTEXFS_SUPER_MAGIC = 0xbad1dea F_ADD_SEALS = 0x409 + F_CREATED_QUERY = 0x404 F_DUPFD = 0x0 F_DUPFD_CLOEXEC = 0x406 + F_DUPFD_QUERY = 0x403 F_EXLCK = 0x4 F_GETFD = 0x1 F_GETFL = 0x3 @@ -1545,6 +1554,7 @@ const ( IPPROTO_ROUTING = 0x2b IPPROTO_RSVP = 0x2e IPPROTO_SCTP = 0x84 + IPPROTO_SMC = 0x100 IPPROTO_TCP = 0x6 IPPROTO_TP = 0x1d IPPROTO_UDP = 0x11 @@ -1617,6 +1627,8 @@ const ( IPV6_UNICAST_IF = 0x4c IPV6_USER_FLOW = 0xe IPV6_V6ONLY = 0x1a + IPV6_VERSION = 0x60 + IPV6_VERSION_MASK = 0xf0 IPV6_XFRM_POLICY = 0x23 IP_ADD_MEMBERSHIP = 0x23 IP_ADD_SOURCE_MEMBERSHIP = 0x27 @@ -1798,6 +1810,8 @@ const ( LANDLOCK_ACCESS_NET_BIND_TCP = 0x1 LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2 LANDLOCK_CREATE_RULESET_VERSION = 0x1 + LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET = 0x1 + LANDLOCK_SCOPE_SIGNAL = 0x2 LINUX_REBOOT_CMD_CAD_OFF = 0x0 LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef LINUX_REBOOT_CMD_HALT = 0xcdef0123 @@ -1859,6 +1873,7 @@ const ( MADV_UNMERGEABLE = 0xd MADV_WILLNEED = 0x3 MADV_WIPEONFORK = 0x12 + MAP_DROPPABLE = 0x8 MAP_FILE = 0x0 MAP_FIXED = 0x10 MAP_FIXED_NOREPLACE = 0x100000 @@ -1922,6 +1937,8 @@ const ( MNT_EXPIRE = 0x4 MNT_FORCE = 0x1 MNT_ID_REQ_SIZE_VER0 = 0x18 + MNT_ID_REQ_SIZE_VER1 = 0x20 + MNT_NS_INFO_SIZE_VER0 = 0x10 MODULE_INIT_COMPRESSED_FILE = 0x4 MODULE_INIT_IGNORE_MODVERSIONS = 0x1 MODULE_INIT_IGNORE_VERMAGIC = 0x2 @@ -1957,6 +1974,7 @@ const ( MSG_PEEK = 0x2 MSG_PROXY = 0x10 MSG_RST = 0x1000 + MSG_SOCK_DEVMEM = 0x2000000 MSG_SYN = 0x400 MSG_TRUNC = 0x20 MSG_TRYHARD = 0x4 @@ -2073,6 +2091,7 @@ const ( NFC_ATR_REQ_MAXSIZE = 0x40 NFC_ATR_RES_GB_MAXSIZE = 0x2f NFC_ATR_RES_MAXSIZE = 0x40 + NFC_ATS_MAXSIZE = 0x14 NFC_COMM_ACTIVE = 0x0 NFC_COMM_PASSIVE = 0x1 NFC_DEVICE_NAME_MAXSIZE = 0x8 @@ -2153,6 +2172,7 @@ const ( NFNL_SUBSYS_QUEUE = 0x3 NFNL_SUBSYS_ULOG = 0x4 NFS_SUPER_MAGIC = 0x6969 + NFT_BITWISE_BOOL = 0x0 NFT_CHAIN_FLAGS = 0x7 NFT_CHAIN_MAXNAMELEN = 0x100 NFT_CT_MAX = 0x17 @@ -2187,7 +2207,7 @@ const ( NFT_REG_SIZE = 0x10 NFT_REJECT_ICMPX_MAX = 0x3 NFT_RT_MAX = 0x4 - NFT_SECMARK_CTX_MAXLEN = 0x100 + NFT_SECMARK_CTX_MAXLEN = 0x1000 NFT_SET_MAXNAMELEN = 0x100 NFT_SOCKET_MAX = 0x3 NFT_TABLE_F_MASK = 0x7 @@ -2356,9 +2376,11 @@ const ( PERF_MEM_LVLNUM_IO = 0xa PERF_MEM_LVLNUM_L1 = 0x1 PERF_MEM_LVLNUM_L2 = 0x2 + PERF_MEM_LVLNUM_L2_MHB = 0x5 PERF_MEM_LVLNUM_L3 = 0x3 PERF_MEM_LVLNUM_L4 = 0x4 PERF_MEM_LVLNUM_LFB = 0xc + PERF_MEM_LVLNUM_MSC = 0x6 PERF_MEM_LVLNUM_NA = 0xf PERF_MEM_LVLNUM_PMEM = 0xe PERF_MEM_LVLNUM_RAM = 0xd @@ -2431,6 +2453,7 @@ const ( PRIO_PGRP = 0x1 PRIO_PROCESS = 0x0 PRIO_USER = 0x2 + PROCFS_IOCTL_MAGIC = 'f' PROC_SUPER_MAGIC = 0x9fa0 PROT_EXEC = 0x4 PROT_GROWSDOWN = 0x1000000 @@ -2478,6 +2501,7 @@ const ( PR_GET_PDEATHSIG = 0x2 PR_GET_SECCOMP = 0x15 PR_GET_SECUREBITS = 0x1b + PR_GET_SHADOW_STACK_STATUS = 0x4a PR_GET_SPECULATION_CTRL = 0x34 PR_GET_TAGGED_ADDR_CTRL = 0x38 PR_GET_THP_DISABLE = 0x2a @@ -2486,6 +2510,7 @@ const ( PR_GET_TIMING = 0xd PR_GET_TSC = 0x19 PR_GET_UNALIGN = 0x5 + PR_LOCK_SHADOW_STACK_STATUS = 0x4c PR_MCE_KILL = 0x21 PR_MCE_KILL_CLEAR = 0x0 PR_MCE_KILL_DEFAULT = 0x2 @@ -2512,6 +2537,8 @@ const ( PR_PAC_GET_ENABLED_KEYS = 0x3d PR_PAC_RESET_KEYS = 0x36 PR_PAC_SET_ENABLED_KEYS = 0x3c + PR_PMLEN_MASK = 0x7f000000 + PR_PMLEN_SHIFT = 0x18 PR_PPC_DEXCR_CTRL_CLEAR = 0x4 PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC = 0x10 PR_PPC_DEXCR_CTRL_EDITABLE = 0x1 @@ -2579,6 +2606,7 @@ const ( PR_SET_PTRACER = 0x59616d61 PR_SET_SECCOMP = 0x16 PR_SET_SECUREBITS = 0x1c + PR_SET_SHADOW_STACK_STATUS = 0x4b PR_SET_SPECULATION_CTRL = 0x35 PR_SET_SYSCALL_USER_DISPATCH = 0x3b PR_SET_TAGGED_ADDR_CTRL = 0x37 @@ -2589,6 +2617,9 @@ const ( PR_SET_UNALIGN = 0x6 PR_SET_VMA = 0x53564d41 PR_SET_VMA_ANON_NAME = 0x0 + PR_SHADOW_STACK_ENABLE = 0x1 + PR_SHADOW_STACK_PUSH = 0x4 + PR_SHADOW_STACK_WRITE = 0x2 PR_SME_GET_VL = 0x40 PR_SME_SET_VL = 0x3f PR_SME_SET_VL_ONEXEC = 0x40000 @@ -2620,6 +2651,28 @@ const ( PR_UNALIGN_NOPRINT = 0x1 PR_UNALIGN_SIGBUS = 0x2 PSTOREFS_MAGIC = 0x6165676c + PTP_CLK_MAGIC = '=' + PTP_ENABLE_FEATURE = 0x1 + PTP_EXTTS_EDGES = 0x6 + PTP_EXTTS_EVENT_VALID = 0x1 + PTP_EXTTS_V1_VALID_FLAGS = 0x7 + PTP_EXTTS_VALID_FLAGS = 0x1f + PTP_EXT_OFFSET = 0x10 + PTP_FALLING_EDGE = 0x4 + PTP_MAX_SAMPLES = 0x19 + PTP_PEROUT_DUTY_CYCLE = 0x2 + PTP_PEROUT_ONE_SHOT = 0x1 + PTP_PEROUT_PHASE = 0x4 + PTP_PEROUT_V1_VALID_FLAGS = 0x0 + PTP_PEROUT_VALID_FLAGS = 0x7 + PTP_PIN_GETFUNC = 0xc0603d06 + PTP_PIN_GETFUNC2 = 0xc0603d0f + PTP_RISING_EDGE = 0x2 + PTP_STRICT_FLAGS = 0x8 + PTP_SYS_OFFSET_EXTENDED = 0xc4c03d09 + PTP_SYS_OFFSET_EXTENDED2 = 0xc4c03d12 + PTP_SYS_OFFSET_PRECISE = 0xc0403d08 + PTP_SYS_OFFSET_PRECISE2 = 0xc0403d11 PTRACE_ATTACH = 0x10 PTRACE_CONT = 0x7 PTRACE_DETACH = 0x11 @@ -2876,7 +2929,6 @@ const ( RTM_NEWNEXTHOP = 0x68 RTM_NEWNEXTHOPBUCKET = 0x74 RTM_NEWNSID = 0x58 - RTM_NEWNVLAN = 0x70 RTM_NEWPREFIX = 0x34 RTM_NEWQDISC = 0x24 RTM_NEWROUTE = 0x18 @@ -2885,6 +2937,7 @@ const ( RTM_NEWTCLASS = 0x28 RTM_NEWTFILTER = 0x2c RTM_NEWTUNNEL = 0x78 + RTM_NEWVLAN = 0x70 RTM_NR_FAMILIES = 0x1b RTM_NR_MSGTYPES = 0x6c RTM_SETDCB = 0x4f @@ -2933,15 +2986,17 @@ const ( RUSAGE_SELF = 0x0 RUSAGE_THREAD = 0x1 RWF_APPEND = 0x10 + RWF_ATOMIC = 0x40 RWF_DSYNC = 0x2 RWF_HIPRI = 0x1 RWF_NOAPPEND = 0x20 RWF_NOWAIT = 0x8 - RWF_SUPPORTED = 0x3f + RWF_SUPPORTED = 0x7f RWF_SYNC = 0x4 RWF_WRITE_LIFE_NOT_SET = 0x0 SCHED_BATCH = 0x3 SCHED_DEADLINE = 0x6 + SCHED_EXT = 0x7 SCHED_FIFO = 0x1 SCHED_FLAG_ALL = 0x7f SCHED_FLAG_DL_OVERRUN = 0x4 @@ -3210,6 +3265,7 @@ const ( STATX_ATTR_MOUNT_ROOT = 0x2000 STATX_ATTR_NODUMP = 0x40 STATX_ATTR_VERITY = 0x100000 + STATX_ATTR_WRITE_ATOMIC = 0x400000 STATX_BASIC_STATS = 0x7ff STATX_BLOCKS = 0x400 STATX_BTIME = 0x800 @@ -3226,6 +3282,7 @@ const ( STATX_SUBVOL = 0x8000 STATX_TYPE = 0x1 STATX_UID = 0x8 + STATX_WRITE_ATOMIC = 0x10000 STATX__RESERVED = 0x80000000 SYNC_FILE_RANGE_WAIT_AFTER = 0x4 SYNC_FILE_RANGE_WAIT_BEFORE = 0x1 @@ -3624,6 +3681,7 @@ const ( XDP_UMEM_PGOFF_COMPLETION_RING = 0x180000000 XDP_UMEM_PGOFF_FILL_RING = 0x100000000 XDP_UMEM_REG = 0x4 + XDP_UMEM_TX_METADATA_LEN = 0x4 XDP_UMEM_TX_SW_CSUM = 0x2 XDP_UMEM_UNALIGNED_CHUNK_FLAG = 0x1 XDP_USE_NEED_WAKEUP = 0x8 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 684a5168dac4e3a9cbc4bb6c0bc3dc8259371f06..75207613c785dbe3fb5e9afd152330e4ff342de3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -109,12 +109,15 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -153,9 +156,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 @@ -232,6 +240,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffff + PTP_CLOCK_GETCAPS = 0x80503d01 + PTP_CLOCK_GETCAPS2 = 0x80503d0a + PTP_ENABLE_PPS = 0x40043d04 + PTP_ENABLE_PPS2 = 0x40043d0d + PTP_EXTTS_REQUEST = 0x40103d02 + PTP_EXTTS_REQUEST2 = 0x40103d0b + PTP_MASK_CLEAR_ALL = 0x3d13 + PTP_MASK_EN_SINGLE = 0x40043d14 + PTP_PEROUT_REQUEST = 0x40383d03 + PTP_PEROUT_REQUEST2 = 0x40383d0c + PTP_PIN_SETFUNC = 0x40603d07 + PTP_PIN_SETFUNC2 = 0x40603d10 + PTP_SYS_OFFSET = 0x43403d05 + PTP_SYS_OFFSET2 = 0x43403d0e PTRACE_GETFPREGS = 0xe PTRACE_GETFPXREGS = 0x12 PTRACE_GET_THREAD_AREA = 0x19 @@ -278,10 +300,13 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 @@ -316,6 +341,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index 61d74b592d68647f5ec4daffe64daca8d8ff0870..c68acda53522d124fc1ef7c7dc889394ca4103ab 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -109,12 +109,15 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -153,9 +156,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 @@ -232,6 +240,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x80503d01 + PTP_CLOCK_GETCAPS2 = 0x80503d0a + PTP_ENABLE_PPS = 0x40043d04 + PTP_ENABLE_PPS2 = 0x40043d0d + PTP_EXTTS_REQUEST = 0x40103d02 + PTP_EXTTS_REQUEST2 = 0x40103d0b + PTP_MASK_CLEAR_ALL = 0x3d13 + PTP_MASK_EN_SINGLE = 0x40043d14 + PTP_PEROUT_REQUEST = 0x40383d03 + PTP_PEROUT_REQUEST2 = 0x40383d0c + PTP_PIN_SETFUNC = 0x40603d07 + PTP_PIN_SETFUNC2 = 0x40603d10 + PTP_SYS_OFFSET = 0x43403d05 + PTP_SYS_OFFSET2 = 0x43403d0e PTRACE_ARCH_PRCTL = 0x1e PTRACE_GETFPREGS = 0xe PTRACE_GETFPXREGS = 0x12 @@ -279,10 +301,13 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 @@ -317,6 +342,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index a28c9e3e893adb63c98bad863878601f8d2ae217..a8c607ab86b51b1e69629a7131b674a533c1a05f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -150,9 +153,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 @@ -229,6 +237,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffff + PTP_CLOCK_GETCAPS = 0x80503d01 + PTP_CLOCK_GETCAPS2 = 0x80503d0a + PTP_ENABLE_PPS = 0x40043d04 + PTP_ENABLE_PPS2 = 0x40043d0d + PTP_EXTTS_REQUEST = 0x40103d02 + PTP_EXTTS_REQUEST2 = 0x40103d0b + PTP_MASK_CLEAR_ALL = 0x3d13 + PTP_MASK_EN_SINGLE = 0x40043d14 + PTP_PEROUT_REQUEST = 0x40383d03 + PTP_PEROUT_REQUEST2 = 0x40383d0c + PTP_PIN_SETFUNC = 0x40603d07 + PTP_PIN_SETFUNC2 = 0x40603d10 + PTP_SYS_OFFSET = 0x43403d05 + PTP_SYS_OFFSET2 = 0x43403d0e PTRACE_GETCRUNCHREGS = 0x19 PTRACE_GETFDPIC = 0x1f PTRACE_GETFDPIC_EXEC = 0x0 @@ -284,10 +306,13 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 @@ -322,6 +347,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index ab5d1fe8ead78b400d50ada17cc0a8c203e166fe..18563dd8d33a0f8e7a343377cd529ddf3eeb47fc 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -109,15 +109,19 @@ const ( F_SETOWN = 0x8 F_UNLCK = 0x2 F_WRLCK = 0x1 + GCS_MAGIC = 0x47435300 HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -154,9 +158,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 @@ -200,6 +209,7 @@ const ( PERF_EVENT_IOC_SET_BPF = 0x40042408 PERF_EVENT_IOC_SET_FILTER = 0x40082406 PERF_EVENT_IOC_SET_OUTPUT = 0x2405 + POE_MAGIC = 0x504f4530 PPPIOCATTACH = 0x4004743d PPPIOCATTCHAN = 0x40047438 PPPIOCBRIDGECHAN = 0x40047435 @@ -235,6 +245,20 @@ const ( PROT_BTI = 0x10 PROT_MTE = 0x20 PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x80503d01 + PTP_CLOCK_GETCAPS2 = 0x80503d0a + PTP_ENABLE_PPS = 0x40043d04 + PTP_ENABLE_PPS2 = 0x40043d0d + PTP_EXTTS_REQUEST = 0x40103d02 + PTP_EXTTS_REQUEST2 = 0x40103d0b + PTP_MASK_CLEAR_ALL = 0x3d13 + PTP_MASK_EN_SINGLE = 0x40043d14 + PTP_PEROUT_REQUEST = 0x40383d03 + PTP_PEROUT_REQUEST2 = 0x40383d0c + PTP_PIN_SETFUNC = 0x40603d07 + PTP_PIN_SETFUNC2 = 0x40603d10 + PTP_SYS_OFFSET = 0x43403d05 + PTP_SYS_OFFSET2 = 0x43403d0e PTRACE_PEEKMTETAGS = 0x21 PTRACE_POKEMTETAGS = 0x22 PTRACE_SYSEMU = 0x1f @@ -275,10 +299,13 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 @@ -313,6 +340,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index c523090e7c17e0ada43acb248c94934f4f29a150..22912cdaa94483d6a5a2759d4d05b72663fce96b 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -109,12 +109,15 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -154,9 +157,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 @@ -233,6 +241,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x80503d01 + PTP_CLOCK_GETCAPS2 = 0x80503d0a + PTP_ENABLE_PPS = 0x40043d04 + PTP_ENABLE_PPS2 = 0x40043d0d + PTP_EXTTS_REQUEST = 0x40103d02 + PTP_EXTTS_REQUEST2 = 0x40103d0b + PTP_MASK_CLEAR_ALL = 0x3d13 + PTP_MASK_EN_SINGLE = 0x40043d14 + PTP_PEROUT_REQUEST = 0x40383d03 + PTP_PEROUT_REQUEST2 = 0x40383d0c + PTP_PIN_SETFUNC = 0x40603d07 + PTP_PIN_SETFUNC2 = 0x40603d10 + PTP_SYS_OFFSET = 0x43403d05 + PTP_SYS_OFFSET2 = 0x43403d0e PTRACE_SYSEMU = 0x1f PTRACE_SYSEMU_SINGLESTEP = 0x20 RLIMIT_AS = 0x9 @@ -271,10 +293,13 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 @@ -309,6 +334,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 01e6ea7804b12a83847f59ac0464a0ecfa2f211a..29344eb37ab55a5982a044ccd388638be2ce0f23 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -150,9 +153,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 @@ -229,6 +237,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x20007434 PPPIOCXFERUNIT = 0x2000744e PR_SET_PTRACER_ANY = 0xffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETFPREGS = 0xe PTRACE_GET_THREAD_AREA = 0x19 PTRACE_GET_THREAD_AREA_3264 = 0xc4 @@ -277,10 +299,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 @@ -315,6 +340,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 7aa610b1e717baf92c32d098beeb1df9cd1223fe..20d51fb96a897f5c675d91b1107efa1b0956c3b0 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -150,9 +153,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 @@ -229,6 +237,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x20007434 PPPIOCXFERUNIT = 0x2000744e PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETFPREGS = 0xe PTRACE_GET_THREAD_AREA = 0x19 PTRACE_GET_THREAD_AREA_3264 = 0xc4 @@ -277,10 +299,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 @@ -315,6 +340,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index 92af771b44a35026dee5c90b4f28aeeacb69762a..321b60902ae5cd5686f44b8dcf9d742a6df9d30c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -150,9 +153,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 @@ -229,6 +237,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x20007434 PPPIOCXFERUNIT = 0x2000744e PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETFPREGS = 0xe PTRACE_GET_THREAD_AREA = 0x19 PTRACE_GET_THREAD_AREA_3264 = 0xc4 @@ -277,10 +299,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 @@ -315,6 +340,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index b27ef5e6f11952ba929e6659970c6e55b9ee7d34..9bacdf1e27910f1e8f2cb8c582b37f7c54467224 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x80 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -150,9 +153,14 @@ const ( NFDBITS = 0x20 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 @@ -229,6 +237,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x20007434 PPPIOCXFERUNIT = 0x2000744e PR_SET_PTRACER_ANY = 0xffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETFPREGS = 0xe PTRACE_GET_THREAD_AREA = 0x19 PTRACE_GET_THREAD_AREA_3264 = 0xc4 @@ -277,10 +299,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 @@ -315,6 +340,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index 237a2cefb3e5a27bfb7dc72a560c94495270cbaa..c2242726156a94e77d1b3a6b5c8f5e0f61b643f7 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x4000 ICANON = 0x100 IEXTEN = 0x400 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x80 IUCLC = 0x1000 IXOFF = 0x400 @@ -152,9 +155,14 @@ const ( NL3 = 0x300 NLDLY = 0x300 NOFLSH = 0x80000000 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x4 ONLCR = 0x2 @@ -232,6 +240,20 @@ const ( PPPIOCXFERUNIT = 0x2000744e PROT_SAO = 0x10 PR_SET_PTRACER_ANY = 0xffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETEVRREGS = 0x14 PTRACE_GETFPREGS = 0xe PTRACE_GETREGS64 = 0x16 @@ -332,10 +354,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 @@ -370,6 +395,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 4a5c555a36e2bf0383f0094e84e7ced989597391..6270c8ee13e3f5ac37b6954b36ca972696ad092c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x4000 ICANON = 0x100 IEXTEN = 0x400 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x80 IUCLC = 0x1000 IXOFF = 0x400 @@ -152,9 +155,14 @@ const ( NL3 = 0x300 NLDLY = 0x300 NOFLSH = 0x80000000 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x4 ONLCR = 0x2 @@ -232,6 +240,20 @@ const ( PPPIOCXFERUNIT = 0x2000744e PROT_SAO = 0x10 PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETEVRREGS = 0x14 PTRACE_GETFPREGS = 0xe PTRACE_GETREGS64 = 0x16 @@ -336,10 +358,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 @@ -374,6 +399,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index a02fb49a5f8adb3a400876aa44fde5e597205050..9966c1941f8301450c052e12184340b465ad204e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x4000 ICANON = 0x100 IEXTEN = 0x400 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x80 IUCLC = 0x1000 IXOFF = 0x400 @@ -152,9 +155,14 @@ const ( NL3 = 0x300 NLDLY = 0x300 NOFLSH = 0x80000000 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x4 ONLCR = 0x2 @@ -232,6 +240,20 @@ const ( PPPIOCXFERUNIT = 0x2000744e PROT_SAO = 0x10 PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETEVRREGS = 0x14 PTRACE_GETFPREGS = 0xe PTRACE_GETREGS64 = 0x16 @@ -336,10 +358,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 @@ -374,6 +399,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index e26a7c61b2b6fd8edfaf4feb989e013760c7965d..848e5fcc42e6f2f5dcc59d5a5d79199e57a856cb 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xffffff0f + IPV6_FLOWLABEL_MASK = 0xffff0f00 ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -150,9 +153,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 @@ -229,6 +237,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x80503d01 + PTP_CLOCK_GETCAPS2 = 0x80503d0a + PTP_ENABLE_PPS = 0x40043d04 + PTP_ENABLE_PPS2 = 0x40043d0d + PTP_EXTTS_REQUEST = 0x40103d02 + PTP_EXTTS_REQUEST2 = 0x40103d0b + PTP_MASK_CLEAR_ALL = 0x3d13 + PTP_MASK_EN_SINGLE = 0x40043d14 + PTP_PEROUT_REQUEST = 0x40383d03 + PTP_PEROUT_REQUEST2 = 0x40383d0c + PTP_PIN_SETFUNC = 0x40603d07 + PTP_PIN_SETFUNC2 = 0x40603d10 + PTP_SYS_OFFSET = 0x43403d05 + PTP_SYS_OFFSET2 = 0x43403d0e PTRACE_GETFDPIC = 0x21 PTRACE_GETFDPIC_EXEC = 0x0 PTRACE_GETFDPIC_INTERP = 0x1 @@ -268,10 +290,13 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 @@ -306,6 +331,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index c48f7c2103b81350e8af69d8b83cc6fa25d1a7a1..669b2adb80b778d9daf8400dd00cbab41c0ea5d1 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -108,12 +108,15 @@ const ( HIDIOCGRAWINFO = 0x80084803 HIDIOCGRDESC = 0x90044802 HIDIOCGRDESCSIZE = 0x80044801 + HIDIOCREVOKE = 0x4004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 IN_CLOEXEC = 0x80000 IN_NONBLOCK = 0x800 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -150,9 +153,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x8008b705 NS_GET_NSTYPE = 0xb703 NS_GET_OWNER_UID = 0xb704 NS_GET_PARENT = 0xb702 + NS_GET_PID_FROM_PIDNS = 0x8004b706 + NS_GET_PID_IN_PIDNS = 0x8004b708 + NS_GET_TGID_FROM_PIDNS = 0x8004b707 + NS_GET_TGID_IN_PIDNS = 0x8004b709 NS_GET_USERNS = 0xb701 OLCUC = 0x2 ONLCR = 0x4 @@ -229,6 +237,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x7434 PPPIOCXFERUNIT = 0x744e PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x80503d01 + PTP_CLOCK_GETCAPS2 = 0x80503d0a + PTP_ENABLE_PPS = 0x40043d04 + PTP_ENABLE_PPS2 = 0x40043d0d + PTP_EXTTS_REQUEST = 0x40103d02 + PTP_EXTTS_REQUEST2 = 0x40103d0b + PTP_MASK_CLEAR_ALL = 0x3d13 + PTP_MASK_EN_SINGLE = 0x40043d14 + PTP_PEROUT_REQUEST = 0x40383d03 + PTP_PEROUT_REQUEST2 = 0x40383d0c + PTP_PIN_SETFUNC = 0x40603d07 + PTP_PIN_SETFUNC2 = 0x40603d10 + PTP_SYS_OFFSET = 0x43403d05 + PTP_SYS_OFFSET2 = 0x43403d0e PTRACE_DISABLE_TE = 0x5010 PTRACE_ENABLE_TE = 0x5009 PTRACE_GET_LAST_BREAK = 0x5006 @@ -340,10 +362,13 @@ const ( RTC_WIE_ON = 0x700f RTC_WKALM_RD = 0x80287010 RTC_WKALM_SET = 0x4028700f + SCM_DEVMEM_DMABUF = 0x4f + SCM_DEVMEM_LINEAR = 0x4e SCM_TIMESTAMPING = 0x25 SCM_TIMESTAMPING_OPT_STATS = 0x36 SCM_TIMESTAMPING_PKTINFO = 0x3a SCM_TIMESTAMPNS = 0x23 + SCM_TS_OPT_ID = 0x51 SCM_TXTIME = 0x3d SCM_WIFI_STATUS = 0x29 SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103 @@ -378,6 +403,9 @@ const ( SO_CNX_ADVICE = 0x35 SO_COOKIE = 0x39 SO_DETACH_REUSEPORT_BPF = 0x44 + SO_DEVMEM_DMABUF = 0x4f + SO_DEVMEM_DONTNEED = 0x50 + SO_DEVMEM_LINEAR = 0x4e SO_DOMAIN = 0x27 SO_DONTROUTE = 0x5 SO_ERROR = 0x4 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index ad4b9aace7bb6f7eb581f41398aa987f9436ef3a..4834e57514e44a7f8ca60a6a29e241ac1dba1c77 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -112,12 +112,15 @@ const ( HIDIOCGRAWINFO = 0x40084803 HIDIOCGRDESC = 0x50044802 HIDIOCGRDESCSIZE = 0x40044801 + HIDIOCREVOKE = 0x8004480d HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 IN_CLOEXEC = 0x400000 IN_NONBLOCK = 0x4000 IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9 + IPV6_FLOWINFO_MASK = 0xfffffff + IPV6_FLOWLABEL_MASK = 0xfffff ISIG = 0x1 IUCLC = 0x200 IXOFF = 0x1000 @@ -155,9 +158,14 @@ const ( NFDBITS = 0x40 NLDLY = 0x100 NOFLSH = 0x80 + NS_GET_MNTNS_ID = 0x4008b705 NS_GET_NSTYPE = 0x2000b703 NS_GET_OWNER_UID = 0x2000b704 NS_GET_PARENT = 0x2000b702 + NS_GET_PID_FROM_PIDNS = 0x4004b706 + NS_GET_PID_IN_PIDNS = 0x4004b708 + NS_GET_TGID_FROM_PIDNS = 0x4004b707 + NS_GET_TGID_IN_PIDNS = 0x4004b709 NS_GET_USERNS = 0x2000b701 OLCUC = 0x2 ONLCR = 0x4 @@ -234,6 +242,20 @@ const ( PPPIOCUNBRIDGECHAN = 0x20007434 PPPIOCXFERUNIT = 0x2000744e PR_SET_PTRACER_ANY = 0xffffffffffffffff + PTP_CLOCK_GETCAPS = 0x40503d01 + PTP_CLOCK_GETCAPS2 = 0x40503d0a + PTP_ENABLE_PPS = 0x80043d04 + PTP_ENABLE_PPS2 = 0x80043d0d + PTP_EXTTS_REQUEST = 0x80103d02 + PTP_EXTTS_REQUEST2 = 0x80103d0b + PTP_MASK_CLEAR_ALL = 0x20003d13 + PTP_MASK_EN_SINGLE = 0x80043d14 + PTP_PEROUT_REQUEST = 0x80383d03 + PTP_PEROUT_REQUEST2 = 0x80383d0c + PTP_PIN_SETFUNC = 0x80603d07 + PTP_PIN_SETFUNC2 = 0x80603d10 + PTP_SYS_OFFSET = 0x83403d05 + PTP_SYS_OFFSET2 = 0x83403d0e PTRACE_GETFPAREGS = 0x14 PTRACE_GETFPREGS = 0xe PTRACE_GETFPREGS64 = 0x19 @@ -331,10 +353,13 @@ const ( RTC_WIE_ON = 0x2000700f RTC_WKALM_RD = 0x40287010 RTC_WKALM_SET = 0x8028700f + SCM_DEVMEM_DMABUF = 0x58 + SCM_DEVMEM_LINEAR = 0x57 SCM_TIMESTAMPING = 0x23 SCM_TIMESTAMPING_OPT_STATS = 0x38 SCM_TIMESTAMPING_PKTINFO = 0x3c SCM_TIMESTAMPNS = 0x21 + SCM_TS_OPT_ID = 0x5a SCM_TXTIME = 0x3f SCM_WIFI_STATUS = 0x25 SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103 @@ -417,6 +442,9 @@ const ( SO_CNX_ADVICE = 0x37 SO_COOKIE = 0x3b SO_DETACH_REUSEPORT_BPF = 0x47 + SO_DEVMEM_DMABUF = 0x58 + SO_DEVMEM_DONTNEED = 0x59 + SO_DEVMEM_LINEAR = 0x57 SO_DOMAIN = 0x1029 SO_DONTROUTE = 0x10 SO_ERROR = 0x1007 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 1bc1a5adb25fde8aae979c74220db4ae26aea523..5cc1e8eb2f35e097af432fd2273a2a73c1d35b36 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -592,6 +592,16 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func ClockSettime(clockid int32, time *Timespec) (err error) { + _, _, e1 := Syscall(SYS_CLOCK_SETTIME, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) { _, _, e1 := Syscall6(SYS_CLOCK_NANOSLEEP, uintptr(clockid), uintptr(flags), uintptr(unsafe.Pointer(request)), uintptr(unsafe.Pointer(remain)), 0, 0) if e1 != 0 { @@ -971,23 +981,6 @@ func Getpriority(which int, who int) (prio int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Getrandom(buf []byte, flags int) (n int, err error) { - var _p0 unsafe.Pointer - if len(buf) > 0 { - _p0 = unsafe.Pointer(&buf[0]) - } else { - _p0 = unsafe.Pointer(&_zero) - } - r0, _, e1 := Syscall(SYS_GETRANDOM, uintptr(_p0), uintptr(len(buf)), uintptr(flags)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Getrusage(who int, rusage *Rusage) (err error) { _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go index 829b87feb8da62f255f3b0662ed64cde8c2d01f7..c6545413c45b44cfa7876eb1ce27a1848c79b192 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go @@ -141,6 +141,16 @@ import ( //go:cgo_import_dynamic libc_getpeername getpeername "libsocket.so" //go:cgo_import_dynamic libc_setsockopt setsockopt "libsocket.so" //go:cgo_import_dynamic libc_recvfrom recvfrom "libsocket.so" +//go:cgo_import_dynamic libc_getpeerucred getpeerucred "libc.so" +//go:cgo_import_dynamic libc_ucred_get ucred_get "libc.so" +//go:cgo_import_dynamic libc_ucred_geteuid ucred_geteuid "libc.so" +//go:cgo_import_dynamic libc_ucred_getegid ucred_getegid "libc.so" +//go:cgo_import_dynamic libc_ucred_getruid ucred_getruid "libc.so" +//go:cgo_import_dynamic libc_ucred_getrgid ucred_getrgid "libc.so" +//go:cgo_import_dynamic libc_ucred_getsuid ucred_getsuid "libc.so" +//go:cgo_import_dynamic libc_ucred_getsgid ucred_getsgid "libc.so" +//go:cgo_import_dynamic libc_ucred_getpid ucred_getpid "libc.so" +//go:cgo_import_dynamic libc_ucred_free ucred_free "libc.so" //go:cgo_import_dynamic libc_port_create port_create "libc.so" //go:cgo_import_dynamic libc_port_associate port_associate "libc.so" //go:cgo_import_dynamic libc_port_dissociate port_dissociate "libc.so" @@ -280,6 +290,16 @@ import ( //go:linkname procgetpeername libc_getpeername //go:linkname procsetsockopt libc_setsockopt //go:linkname procrecvfrom libc_recvfrom +//go:linkname procgetpeerucred libc_getpeerucred +//go:linkname procucred_get libc_ucred_get +//go:linkname procucred_geteuid libc_ucred_geteuid +//go:linkname procucred_getegid libc_ucred_getegid +//go:linkname procucred_getruid libc_ucred_getruid +//go:linkname procucred_getrgid libc_ucred_getrgid +//go:linkname procucred_getsuid libc_ucred_getsuid +//go:linkname procucred_getsgid libc_ucred_getsgid +//go:linkname procucred_getpid libc_ucred_getpid +//go:linkname procucred_free libc_ucred_free //go:linkname procport_create libc_port_create //go:linkname procport_associate libc_port_associate //go:linkname procport_dissociate libc_port_dissociate @@ -420,6 +440,16 @@ var ( procgetpeername, procsetsockopt, procrecvfrom, + procgetpeerucred, + procucred_get, + procucred_geteuid, + procucred_getegid, + procucred_getruid, + procucred_getrgid, + procucred_getsuid, + procucred_getsgid, + procucred_getpid, + procucred_free, procport_create, procport_associate, procport_dissociate, @@ -2029,6 +2059,90 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func getpeerucred(fd uintptr, ucred *uintptr) (err error) { + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetpeerucred)), 2, uintptr(fd), uintptr(unsafe.Pointer(ucred)), 0, 0, 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGet(pid int) (ucred uintptr, err error) { + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procucred_get)), 1, uintptr(pid), 0, 0, 0, 0, 0) + ucred = uintptr(r0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGeteuid(ucred uintptr) (uid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_geteuid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetegid(ucred uintptr) (gid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getegid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + gid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetruid(ucred uintptr) (uid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getruid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetrgid(ucred uintptr) (gid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getrgid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + gid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetsuid(ucred uintptr) (uid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getsuid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + uid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetsgid(ucred uintptr) (gid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getsgid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + gid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredGetpid(ucred uintptr) (pid int) { + r0, _, _ := sysvicall6(uintptr(unsafe.Pointer(&procucred_getpid)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + pid = int(r0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func ucredFree(ucred uintptr) { + sysvicall6(uintptr(unsafe.Pointer(&procucred_free)), 1, uintptr(ucred), 0, 0, 0, 0, 0) + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func port_create() (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procport_create)), 0, 0, 0, 0, 0, 0, 0) n = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index 524b0820cbc2ee32a4598fa64ebbe64cec2a9dda..c79aaff306ae3eebf5d338ac84c4d478f566c485 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -458,4 +458,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index d3e38f681ab0345eac069c79580f7f9cba3d4b7a..5eb450695e95a819f1756ff2241adda0588cf628 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -341,6 +341,7 @@ const ( SYS_STATX = 332 SYS_IO_PGETEVENTS = 333 SYS_RSEQ = 334 + SYS_URETPROBE = 335 SYS_PIDFD_SEND_SIGNAL = 424 SYS_IO_URING_SETUP = 425 SYS_IO_URING_ENTER = 426 @@ -380,4 +381,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index 70b35bf3b09f68cb6bd6c4065b4248ed02657766..05e5029744586103a94d9482fe3dac1bb9ca607f 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -422,4 +422,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index 6c778c23278f923fc4424265cacc92280877460f..38c53ec51bb3e6b6fff2b168f1351758d99b6b05 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -85,7 +85,7 @@ const ( SYS_SPLICE = 76 SYS_TEE = 77 SYS_READLINKAT = 78 - SYS_FSTATAT = 79 + SYS_NEWFSTATAT = 79 SYS_FSTAT = 80 SYS_SYNC = 81 SYS_FSYNC = 82 @@ -325,4 +325,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go index 37281cf51a80bbcae0342a567bad5da4e089d2d6..31d2e71a18e17f4cd6fdd3a16f8ecffa1c2cdc91 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go @@ -84,6 +84,8 @@ const ( SYS_SPLICE = 76 SYS_TEE = 77 SYS_READLINKAT = 78 + SYS_NEWFSTATAT = 79 + SYS_FSTAT = 80 SYS_SYNC = 81 SYS_FSYNC = 82 SYS_FDATASYNC = 83 @@ -319,4 +321,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index 7e567f1efff21dabc0bbb99d82ac79568fa0c71e..f4184a336b0e02d1ff0a976a4d47d01667072ff7 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -442,4 +442,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 4460 SYS_LSM_LIST_MODULES = 4461 SYS_MSEAL = 4462 + SYS_SETXATTRAT = 4463 + SYS_GETXATTRAT = 4464 + SYS_LISTXATTRAT = 4465 + SYS_REMOVEXATTRAT = 4466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index 38ae55e5ef8564b859a937192e6e7ff9ff75404d..05b9962278f2760f8134c2396859cb9c142fa0a2 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -372,4 +372,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 5460 SYS_LSM_LIST_MODULES = 5461 SYS_MSEAL = 5462 + SYS_SETXATTRAT = 5463 + SYS_GETXATTRAT = 5464 + SYS_LISTXATTRAT = 5465 + SYS_REMOVEXATTRAT = 5466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index 55e92e60a82abed887cc2e86929cf413ccc1f0e7..43a256e9e6758502f2f5883e3c43c29bb05f2bff 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -372,4 +372,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 5460 SYS_LSM_LIST_MODULES = 5461 SYS_MSEAL = 5462 + SYS_SETXATTRAT = 5463 + SYS_GETXATTRAT = 5464 + SYS_LISTXATTRAT = 5465 + SYS_REMOVEXATTRAT = 5466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index 60658d6a021f66f19d23ed38f6eae448f0fa1b21..eea5ddfc220774443034d5ad1b052c17347d626e 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -442,4 +442,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 4460 SYS_LSM_LIST_MODULES = 4461 SYS_MSEAL = 4462 + SYS_SETXATTRAT = 4463 + SYS_GETXATTRAT = 4464 + SYS_LISTXATTRAT = 4465 + SYS_REMOVEXATTRAT = 4466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go index e203e8a7ed4b2c76d1a08ccda193c17f82fc7e93..0d777bfbb1408e2c32b03fdc2b5652157b3872a8 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go @@ -449,4 +449,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index 5944b97d54604ea41a1dea195b26f3bd1f387343..b44636502561e6953318bb9cc942be9616340bc9 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -421,4 +421,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index c66d416dad1ccb56f1196d99545460f9d658f092..0c7d21c18816539b4d6856dbcf44f56b4217c421 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -421,4 +421,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index 9889f6a5591b62a375a69a718b692bcb4328852b..8405391698787a00552d807260232ad8680fd332 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -84,7 +84,7 @@ const ( SYS_SPLICE = 76 SYS_TEE = 77 SYS_READLINKAT = 78 - SYS_FSTATAT = 79 + SYS_NEWFSTATAT = 79 SYS_FSTAT = 80 SYS_SYNC = 81 SYS_FSYNC = 82 @@ -326,4 +326,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index 01d86825bb926417fbc8c9e69c5ecb5bb599d683..fcf1b790d6cfd31996ab2f95beb8f965657e70be 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -387,4 +387,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index 7b703e77cda8450621f3892f1a03d7e698f12cee..52d15b5f9d4597c74ff988c7893a0f2710963e3f 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -400,4 +400,8 @@ const ( SYS_LSM_SET_SELF_ATTR = 460 SYS_LSM_LIST_MODULES = 461 SYS_MSEAL = 462 + SYS_SETXATTRAT = 463 + SYS_GETXATTRAT = 464 + SYS_LISTXATTRAT = 465 + SYS_REMOVEXATTRAT = 466 ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go index d003c3d43780c22bca92bd9426dc7e88bf7b8fb1..17c53bd9b3315aaec65571964e73bb93e6c85175 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_amd64.go @@ -462,11 +462,14 @@ type FdSet struct { const ( SizeofIfMsghdr = 0x70 + SizeofIfMsghdr2 = 0xa0 SizeofIfData = 0x60 + SizeofIfData64 = 0x80 SizeofIfaMsghdr = 0x14 SizeofIfmaMsghdr = 0x10 SizeofIfmaMsghdr2 = 0x14 SizeofRtMsghdr = 0x5c + SizeofRtMsghdr2 = 0x5c SizeofRtMetrics = 0x38 ) @@ -480,6 +483,20 @@ type IfMsghdr struct { Data IfData } +type IfMsghdr2 struct { + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + Snd_len int32 + Snd_maxlen int32 + Snd_drops int32 + Timer int32 + Data IfData64 +} + type IfData struct { Type uint8 Typelen uint8 @@ -512,6 +529,34 @@ type IfData struct { Reserved2 uint32 } +type IfData64 struct { + Type uint8 + Typelen uint8 + Physical uint8 + Addrlen uint8 + Hdrlen uint8 + Recvquota uint8 + Xmitquota uint8 + Unused1 uint8 + Mtu uint32 + Metric uint32 + Baudrate uint64 + Ipackets uint64 + Ierrors uint64 + Opackets uint64 + Oerrors uint64 + Collisions uint64 + Ibytes uint64 + Obytes uint64 + Imcasts uint64 + Omcasts uint64 + Iqdrops uint64 + Noproto uint64 + Recvtiming uint32 + Xmittiming uint32 + Lastchange Timeval32 +} + type IfaMsghdr struct { Msglen uint16 Version uint8 @@ -557,6 +602,21 @@ type RtMsghdr struct { Rmx RtMetrics } +type RtMsghdr2 struct { + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + Flags int32 + Addrs int32 + Refcnt int32 + Parentflags int32 + Reserved int32 + Use int32 + Inits uint32 + Rmx RtMetrics +} + type RtMetrics struct { Locks uint32 Mtu uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go index 0d45a941aaeccff1f29ca0bcfe667984a58f46d0..2392226a743eb3e19c581773191ddbe86eecad53 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_darwin_arm64.go @@ -462,11 +462,14 @@ type FdSet struct { const ( SizeofIfMsghdr = 0x70 + SizeofIfMsghdr2 = 0xa0 SizeofIfData = 0x60 + SizeofIfData64 = 0x80 SizeofIfaMsghdr = 0x14 SizeofIfmaMsghdr = 0x10 SizeofIfmaMsghdr2 = 0x14 SizeofRtMsghdr = 0x5c + SizeofRtMsghdr2 = 0x5c SizeofRtMetrics = 0x38 ) @@ -480,6 +483,20 @@ type IfMsghdr struct { Data IfData } +type IfMsghdr2 struct { + Msglen uint16 + Version uint8 + Type uint8 + Addrs int32 + Flags int32 + Index uint16 + Snd_len int32 + Snd_maxlen int32 + Snd_drops int32 + Timer int32 + Data IfData64 +} + type IfData struct { Type uint8 Typelen uint8 @@ -512,6 +529,34 @@ type IfData struct { Reserved2 uint32 } +type IfData64 struct { + Type uint8 + Typelen uint8 + Physical uint8 + Addrlen uint8 + Hdrlen uint8 + Recvquota uint8 + Xmitquota uint8 + Unused1 uint8 + Mtu uint32 + Metric uint32 + Baudrate uint64 + Ipackets uint64 + Ierrors uint64 + Opackets uint64 + Oerrors uint64 + Collisions uint64 + Ibytes uint64 + Obytes uint64 + Imcasts uint64 + Omcasts uint64 + Iqdrops uint64 + Noproto uint64 + Recvtiming uint32 + Xmittiming uint32 + Lastchange Timeval32 +} + type IfaMsghdr struct { Msglen uint16 Version uint8 @@ -557,6 +602,21 @@ type RtMsghdr struct { Rmx RtMetrics } +type RtMsghdr2 struct { + Msglen uint16 + Version uint8 + Type uint8 + Index uint16 + Flags int32 + Addrs int32 + Refcnt int32 + Parentflags int32 + Reserved int32 + Use int32 + Inits uint32 + Rmx RtMetrics +} + type RtMetrics struct { Locks uint32 Mtu uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index 9f2550dc3120d0979c919fb324f44b02a59a438f..a46abe64720547a72a90330c2aa29113b4ef0552 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -87,31 +87,35 @@ type StatxTimestamp struct { } type Statx_t struct { - Mask uint32 - Blksize uint32 - Attributes uint64 - Nlink uint32 - Uid uint32 - Gid uint32 - Mode uint16 - _ [1]uint16 - Ino uint64 - Size uint64 - Blocks uint64 - Attributes_mask uint64 - Atime StatxTimestamp - Btime StatxTimestamp - Ctime StatxTimestamp - Mtime StatxTimestamp - Rdev_major uint32 - Rdev_minor uint32 - Dev_major uint32 - Dev_minor uint32 - Mnt_id uint64 - Dio_mem_align uint32 - Dio_offset_align uint32 - Subvol uint64 - _ [11]uint64 + Mask uint32 + Blksize uint32 + Attributes uint64 + Nlink uint32 + Uid uint32 + Gid uint32 + Mode uint16 + _ [1]uint16 + Ino uint64 + Size uint64 + Blocks uint64 + Attributes_mask uint64 + Atime StatxTimestamp + Btime StatxTimestamp + Ctime StatxTimestamp + Mtime StatxTimestamp + Rdev_major uint32 + Rdev_minor uint32 + Dev_major uint32 + Dev_minor uint32 + Mnt_id uint64 + Dio_mem_align uint32 + Dio_offset_align uint32 + Subvol uint64 + Atomic_write_unit_min uint32 + Atomic_write_unit_max uint32 + Atomic_write_segments_max uint32 + _ [1]uint32 + _ [9]uint64 } type Fsid struct { @@ -516,6 +520,29 @@ type TCPInfo struct { Total_rto_time uint32 } +type TCPVegasInfo struct { + Enabled uint32 + Rttcnt uint32 + Rtt uint32 + Minrtt uint32 +} + +type TCPDCTCPInfo struct { + Enabled uint16 + Ce_state uint16 + Alpha uint32 + Ab_ecn uint32 + Ab_tot uint32 +} + +type TCPBBRInfo struct { + Bw_lo uint32 + Bw_hi uint32 + Min_rtt uint32 + Pacing_gain uint32 + Cwnd_gain uint32 +} + type CanFilter struct { Id uint32 Mask uint32 @@ -557,6 +584,7 @@ const ( SizeofICMPv6Filter = 0x20 SizeofUcred = 0xc SizeofTCPInfo = 0xf8 + SizeofTCPCCInfo = 0x14 SizeofCanFilter = 0x8 SizeofTCPRepairOpt = 0x8 ) @@ -1724,12 +1752,6 @@ const ( IFLA_IPVLAN_UNSPEC = 0x0 IFLA_IPVLAN_MODE = 0x1 IFLA_IPVLAN_FLAGS = 0x2 - NETKIT_NEXT = -0x1 - NETKIT_PASS = 0x0 - NETKIT_DROP = 0x2 - NETKIT_REDIRECT = 0x7 - NETKIT_L2 = 0x0 - NETKIT_L3 = 0x1 IFLA_NETKIT_UNSPEC = 0x0 IFLA_NETKIT_PEER_INFO = 0x1 IFLA_NETKIT_PRIMARY = 0x2 @@ -1768,6 +1790,7 @@ const ( IFLA_VXLAN_DF = 0x1d IFLA_VXLAN_VNIFILTER = 0x1e IFLA_VXLAN_LOCALBYPASS = 0x1f + IFLA_VXLAN_LABEL_POLICY = 0x20 IFLA_GENEVE_UNSPEC = 0x0 IFLA_GENEVE_ID = 0x1 IFLA_GENEVE_REMOTE = 0x2 @@ -1797,6 +1820,8 @@ const ( IFLA_GTP_ROLE = 0x4 IFLA_GTP_CREATE_SOCKETS = 0x5 IFLA_GTP_RESTART_COUNT = 0x6 + IFLA_GTP_LOCAL = 0x7 + IFLA_GTP_LOCAL6 = 0x8 IFLA_BOND_UNSPEC = 0x0 IFLA_BOND_MODE = 0x1 IFLA_BOND_ACTIVE_SLAVE = 0x2 @@ -1829,6 +1854,7 @@ const ( IFLA_BOND_AD_LACP_ACTIVE = 0x1d IFLA_BOND_MISSED_MAX = 0x1e IFLA_BOND_NS_IP6_TARGET = 0x1f + IFLA_BOND_COUPLED_CONTROL = 0x20 IFLA_BOND_AD_INFO_UNSPEC = 0x0 IFLA_BOND_AD_INFO_AGGREGATOR = 0x1 IFLA_BOND_AD_INFO_NUM_PORTS = 0x2 @@ -1897,6 +1923,7 @@ const ( IFLA_HSR_SEQ_NR = 0x5 IFLA_HSR_VERSION = 0x6 IFLA_HSR_PROTOCOL = 0x7 + IFLA_HSR_INTERLINK = 0x8 IFLA_STATS_UNSPEC = 0x0 IFLA_STATS_LINK_64 = 0x1 IFLA_STATS_LINK_XSTATS = 0x2 @@ -1949,6 +1976,15 @@ const ( IFLA_DSA_MASTER = 0x1 ) +const ( + NETKIT_NEXT = -0x1 + NETKIT_PASS = 0x0 + NETKIT_DROP = 0x2 + NETKIT_REDIRECT = 0x7 + NETKIT_L2 = 0x0 + NETKIT_L3 = 0x1 +) + const ( NF_INET_PRE_ROUTING = 0x0 NF_INET_LOCAL_IN = 0x1 @@ -2558,8 +2594,8 @@ const ( SOF_TIMESTAMPING_BIND_PHC = 0x8000 SOF_TIMESTAMPING_OPT_ID_TCP = 0x10000 - SOF_TIMESTAMPING_LAST = 0x10000 - SOF_TIMESTAMPING_MASK = 0x1ffff + SOF_TIMESTAMPING_LAST = 0x20000 + SOF_TIMESTAMPING_MASK = 0x3ffff SCM_TSTAMP_SND = 0x0 SCM_TSTAMP_SCHED = 0x1 @@ -3505,7 +3541,7 @@ type Nhmsg struct { type NexthopGrp struct { Id uint32 Weight uint8 - Resvd1 uint8 + High uint8 Resvd2 uint16 } @@ -3766,7 +3802,7 @@ const ( ETHTOOL_MSG_PSE_GET = 0x24 ETHTOOL_MSG_PSE_SET = 0x25 ETHTOOL_MSG_RSS_GET = 0x26 - ETHTOOL_MSG_USER_MAX = 0x2b + ETHTOOL_MSG_USER_MAX = 0x2d ETHTOOL_MSG_KERNEL_NONE = 0x0 ETHTOOL_MSG_STRSET_GET_REPLY = 0x1 ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2 @@ -3806,7 +3842,7 @@ const ( ETHTOOL_MSG_MODULE_NTF = 0x24 ETHTOOL_MSG_PSE_GET_REPLY = 0x25 ETHTOOL_MSG_RSS_GET_REPLY = 0x26 - ETHTOOL_MSG_KERNEL_MAX = 0x2b + ETHTOOL_MSG_KERNEL_MAX = 0x2e ETHTOOL_FLAG_COMPACT_BITSETS = 0x1 ETHTOOL_FLAG_OMIT_REPLY = 0x2 ETHTOOL_FLAG_STATS = 0x4 @@ -3814,7 +3850,7 @@ const ( ETHTOOL_A_HEADER_DEV_INDEX = 0x1 ETHTOOL_A_HEADER_DEV_NAME = 0x2 ETHTOOL_A_HEADER_FLAGS = 0x3 - ETHTOOL_A_HEADER_MAX = 0x3 + ETHTOOL_A_HEADER_MAX = 0x4 ETHTOOL_A_BITSET_BIT_UNSPEC = 0x0 ETHTOOL_A_BITSET_BIT_INDEX = 0x1 ETHTOOL_A_BITSET_BIT_NAME = 0x2 @@ -3951,7 +3987,7 @@ const ( ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL = 0x17 ETHTOOL_A_COALESCE_USE_CQE_MODE_TX = 0x18 ETHTOOL_A_COALESCE_USE_CQE_MODE_RX = 0x19 - ETHTOOL_A_COALESCE_MAX = 0x1c + ETHTOOL_A_COALESCE_MAX = 0x1e ETHTOOL_A_PAUSE_UNSPEC = 0x0 ETHTOOL_A_PAUSE_HEADER = 0x1 ETHTOOL_A_PAUSE_AUTONEG = 0x2 @@ -3995,11 +4031,11 @@ const ( ETHTOOL_A_CABLE_RESULT_UNSPEC = 0x0 ETHTOOL_A_CABLE_RESULT_PAIR = 0x1 ETHTOOL_A_CABLE_RESULT_CODE = 0x2 - ETHTOOL_A_CABLE_RESULT_MAX = 0x2 + ETHTOOL_A_CABLE_RESULT_MAX = 0x3 ETHTOOL_A_CABLE_FAULT_LENGTH_UNSPEC = 0x0 ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR = 0x1 ETHTOOL_A_CABLE_FAULT_LENGTH_CM = 0x2 - ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = 0x2 + ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = 0x3 ETHTOOL_A_CABLE_TEST_NTF_STATUS_UNSPEC = 0x0 ETHTOOL_A_CABLE_TEST_NTF_STATUS_STARTED = 0x1 ETHTOOL_A_CABLE_TEST_NTF_STATUS_COMPLETED = 0x2 @@ -4082,6 +4118,107 @@ type EthtoolDrvinfo struct { Regdump_len uint32 } +type EthtoolTsInfo struct { + Cmd uint32 + So_timestamping uint32 + Phc_index int32 + Tx_types uint32 + Tx_reserved [3]uint32 + Rx_filters uint32 + Rx_reserved [3]uint32 +} + +type HwTstampConfig struct { + Flags int32 + Tx_type int32 + Rx_filter int32 +} + +const ( + HWTSTAMP_FILTER_NONE = 0x0 + HWTSTAMP_FILTER_ALL = 0x1 + HWTSTAMP_FILTER_SOME = 0x2 + HWTSTAMP_FILTER_PTP_V1_L4_EVENT = 0x3 + HWTSTAMP_FILTER_PTP_V2_L4_EVENT = 0x6 + HWTSTAMP_FILTER_PTP_V2_L2_EVENT = 0x9 + HWTSTAMP_FILTER_PTP_V2_EVENT = 0xc +) + +const ( + HWTSTAMP_TX_OFF = 0x0 + HWTSTAMP_TX_ON = 0x1 + HWTSTAMP_TX_ONESTEP_SYNC = 0x2 +) + +type ( + PtpClockCaps struct { + Max_adj int32 + N_alarm int32 + N_ext_ts int32 + N_per_out int32 + Pps int32 + N_pins int32 + Cross_timestamping int32 + Adjust_phase int32 + Max_phase_adj int32 + Rsv [11]int32 + } + PtpClockTime struct { + Sec int64 + Nsec uint32 + Reserved uint32 + } + PtpExttsEvent struct { + T PtpClockTime + Index uint32 + Flags uint32 + Rsv [2]uint32 + } + PtpExttsRequest struct { + Index uint32 + Flags uint32 + Rsv [2]uint32 + } + PtpPeroutRequest struct { + StartOrPhase PtpClockTime + Period PtpClockTime + Index uint32 + Flags uint32 + On PtpClockTime + } + PtpPinDesc struct { + Name [64]byte + Index uint32 + Func uint32 + Chan uint32 + Rsv [5]uint32 + } + PtpSysOffset struct { + Samples uint32 + Rsv [3]uint32 + Ts [51]PtpClockTime + } + PtpSysOffsetExtended struct { + Samples uint32 + Clockid int32 + Rsv [2]uint32 + Ts [25][3]PtpClockTime + } + PtpSysOffsetPrecise struct { + Device PtpClockTime + Realtime PtpClockTime + Monoraw PtpClockTime + Rsv [4]uint32 + } +) + +const ( + PTP_PF_NONE = 0x0 + PTP_PF_EXTTS = 0x1 + PTP_PF_PEROUT = 0x2 + PTP_PF_PHYSYNC = 0x3 +) + type ( HIDRawReportDescriptor struct { Size uint32 @@ -4263,6 +4400,7 @@ const ( type LandlockRulesetAttr struct { Access_fs uint64 Access_net uint64 + Scoped uint64 } type LandlockPathBeneathAttr struct { @@ -4609,7 +4747,7 @@ const ( NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca - NL80211_ATTR_MAX = 0x14a + NL80211_ATTR_MAX = 0x14d NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CSA_COUNTERS = 0xce NL80211_ATTR_MAX_MATCH_SETS = 0x85 @@ -5213,7 +5351,7 @@ const ( NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf - NL80211_FREQUENCY_ATTR_MAX = 0x20 + NL80211_FREQUENCY_ATTR_MAX = 0x21 NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6 NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11 NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc @@ -5381,7 +5519,7 @@ const ( NL80211_MNTR_FLAG_CONTROL = 0x3 NL80211_MNTR_FLAG_COOK_FRAMES = 0x5 NL80211_MNTR_FLAG_FCSFAIL = 0x1 - NL80211_MNTR_FLAG_MAX = 0x6 + NL80211_MNTR_FLAG_MAX = 0x7 NL80211_MNTR_FLAG_OTHER_BSS = 0x4 NL80211_MNTR_FLAG_PLCPFAIL = 0x2 NL80211_MPATH_FLAG_ACTIVE = 0x1 @@ -6036,3 +6174,5 @@ type SockDiagReq struct { Family uint8 Protocol uint8 } + +const RTM_NEWNVLAN = 0x70 diff --git a/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go index d9a13af4684b0c370ba506917d95659e782194dc..2e5d5a44357a2e2ae04c8a406d8b89f0042968a9 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_zos_s390x.go @@ -377,6 +377,12 @@ type Flock_t struct { Pid int32 } +type F_cnvrt struct { + Cvtcmd int32 + Pccsid int16 + Fccsid int16 +} + type Termios struct { Cflag uint32 Iflag uint32 diff --git a/vendor/golang.org/x/sys/windows/dll_windows.go b/vendor/golang.org/x/sys/windows/dll_windows.go index 115341fba66dab28536543805dbbdfd3a88500a1..3ca814f54d44eb100e254cebd949d31f0fe22b59 100644 --- a/vendor/golang.org/x/sys/windows/dll_windows.go +++ b/vendor/golang.org/x/sys/windows/dll_windows.go @@ -43,8 +43,8 @@ type DLL struct { // LoadDLL loads DLL file into memory. // // Warning: using LoadDLL without an absolute path name is subject to -// DLL preloading attacks. To safely load a system DLL, use LazyDLL -// with System set to true, or use LoadLibraryEx directly. +// DLL preloading attacks. To safely load a system DLL, use [NewLazySystemDLL], +// or use [LoadLibraryEx] directly. func LoadDLL(name string) (dll *DLL, err error) { namep, err := UTF16PtrFromString(name) if err != nil { @@ -65,7 +65,7 @@ func LoadDLL(name string) (dll *DLL, err error) { return d, nil } -// MustLoadDLL is like LoadDLL but panics if load operation failes. +// MustLoadDLL is like LoadDLL but panics if load operation fails. func MustLoadDLL(name string) *DLL { d, e := LoadDLL(name) if e != nil { @@ -271,6 +271,9 @@ func (d *LazyDLL) NewProc(name string) *LazyProc { } // NewLazyDLL creates new LazyDLL associated with DLL file. +// +// Warning: using NewLazyDLL without an absolute path name is subject to +// DLL preloading attacks. To safely load a system DLL, use [NewLazySystemDLL]. func NewLazyDLL(name string) *LazyDLL { return &LazyDLL{Name: name} } @@ -410,7 +413,3 @@ func loadLibraryEx(name string, system bool) (*DLL, error) { } return &DLL{Name: name, Handle: h}, nil } - -type errString string - -func (s errString) Error() string { return string(s) } diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 5cee9a3143fd5e426980d338925943c4baf862f0..4a32543868500f5403404d54de8f9f5f827e6e18 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -168,6 +168,8 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys CreateNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *SecurityAttributes) (handle Handle, err error) [failretval==InvalidHandle] = CreateNamedPipeW //sys ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error) //sys DisconnectNamedPipe(pipe Handle) (err error) +//sys GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error) +//sys GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error) //sys GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) //sys GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW //sys SetNamedPipeHandleState(pipe Handle, state *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32) (err error) = SetNamedPipeHandleState @@ -725,20 +727,12 @@ func DurationSinceBoot() time.Duration { } func Ftruncate(fd Handle, length int64) (err error) { - curoffset, e := Seek(fd, 0, 1) - if e != nil { - return e - } - defer Seek(fd, curoffset, 0) - _, e = Seek(fd, length, 0) - if e != nil { - return e + type _FILE_END_OF_FILE_INFO struct { + EndOfFile int64 } - e = SetEndOfFile(fd) - if e != nil { - return e - } - return nil + var info _FILE_END_OF_FILE_INFO + info.EndOfFile = length + return SetFileInformationByHandle(fd, FileEndOfFileInfo, (*byte)(unsafe.Pointer(&info)), uint32(unsafe.Sizeof(info))) } func Gettimeofday(tv *Timeval) (err error) { @@ -894,6 +888,11 @@ const socket_error = uintptr(^uint32(0)) //sys GetACP() (acp uint32) = kernel32.GetACP //sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar //sys getBestInterfaceEx(sockaddr unsafe.Pointer, pdwBestIfIndex *uint32) (errcode error) = iphlpapi.GetBestInterfaceEx +//sys GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) = iphlpapi.GetIfEntry2Ex +//sys GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) = iphlpapi.GetUnicastIpAddressEntry +//sys NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyIpInterfaceChange +//sys NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) = iphlpapi.NotifyUnicastIpAddressChange +//sys CancelMibChangeNotify2(notificationHandle Handle) (errcode error) = iphlpapi.CancelMibChangeNotify2 // For testing: clients can set this flag to force // creation of IPv6 sockets to return EAFNOSUPPORT. @@ -1685,13 +1684,16 @@ func (s NTStatus) Error() string { // do not use NTUnicodeString, and instead UTF16PtrFromString should be used for // the more common *uint16 string type. func NewNTUnicodeString(s string) (*NTUnicodeString, error) { - var u NTUnicodeString - s16, err := UTF16PtrFromString(s) + s16, err := UTF16FromString(s) if err != nil { return nil, err } - RtlInitUnicodeString(&u, s16) - return &u, nil + n := uint16(len(s16) * 2) + return &NTUnicodeString{ + Length: n - 2, // subtract 2 bytes for the NULL terminator + MaximumLength: n, + Buffer: &s16[0], + }, nil } // Slice returns a uint16 slice that aliases the data in the NTUnicodeString. diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 7b97a154c9573134f0dfea736baff89b43a586cf..9d138de5fed63ccdc4435228ec96a68c0037bd8c 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -176,6 +176,7 @@ const ( WAIT_FAILED = 0xFFFFFFFF // Access rights for process. + PROCESS_ALL_ACCESS = 0xFFFF PROCESS_CREATE_PROCESS = 0x0080 PROCESS_CREATE_THREAD = 0x0002 PROCESS_DUP_HANDLE = 0x0040 @@ -2203,6 +2204,132 @@ const ( IfOperStatusLowerLayerDown = 7 ) +const ( + IF_MAX_PHYS_ADDRESS_LENGTH = 32 + IF_MAX_STRING_SIZE = 256 +) + +// MIB_IF_ENTRY_LEVEL enumeration from netioapi.h or +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/nf-netioapi-getifentry2ex. +const ( + MibIfEntryNormal = 0 + MibIfEntryNormalWithoutStatistics = 2 +) + +// MIB_NOTIFICATION_TYPE enumeration from netioapi.h or +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ne-netioapi-mib_notification_type. +const ( + MibParameterNotification = 0 + MibAddInstance = 1 + MibDeleteInstance = 2 + MibInitialNotification = 3 +) + +// MibIfRow2 stores information about a particular interface. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_if_row2. +type MibIfRow2 struct { + InterfaceLuid uint64 + InterfaceIndex uint32 + InterfaceGuid GUID + Alias [IF_MAX_STRING_SIZE + 1]uint16 + Description [IF_MAX_STRING_SIZE + 1]uint16 + PhysicalAddressLength uint32 + PhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8 + PermanentPhysicalAddress [IF_MAX_PHYS_ADDRESS_LENGTH]uint8 + Mtu uint32 + Type uint32 + TunnelType uint32 + MediaType uint32 + PhysicalMediumType uint32 + AccessType uint32 + DirectionType uint32 + InterfaceAndOperStatusFlags uint8 + OperStatus uint32 + AdminStatus uint32 + MediaConnectState uint32 + NetworkGuid GUID + ConnectionType uint32 + TransmitLinkSpeed uint64 + ReceiveLinkSpeed uint64 + InOctets uint64 + InUcastPkts uint64 + InNUcastPkts uint64 + InDiscards uint64 + InErrors uint64 + InUnknownProtos uint64 + InUcastOctets uint64 + InMulticastOctets uint64 + InBroadcastOctets uint64 + OutOctets uint64 + OutUcastPkts uint64 + OutNUcastPkts uint64 + OutDiscards uint64 + OutErrors uint64 + OutUcastOctets uint64 + OutMulticastOctets uint64 + OutBroadcastOctets uint64 + OutQLen uint64 +} + +// MIB_UNICASTIPADDRESS_ROW stores information about a unicast IP address. See +// https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_unicastipaddress_row. +type MibUnicastIpAddressRow struct { + Address RawSockaddrInet6 // SOCKADDR_INET union + InterfaceLuid uint64 + InterfaceIndex uint32 + PrefixOrigin uint32 + SuffixOrigin uint32 + ValidLifetime uint32 + PreferredLifetime uint32 + OnLinkPrefixLength uint8 + SkipAsSource uint8 + DadState uint32 + ScopeId uint32 + CreationTimeStamp Filetime +} + +const ScopeLevelCount = 16 + +// MIB_IPINTERFACE_ROW stores interface management information for a particular IP address family on a network interface. +// See https://learn.microsoft.com/en-us/windows/win32/api/netioapi/ns-netioapi-mib_ipinterface_row. +type MibIpInterfaceRow struct { + Family uint16 + InterfaceLuid uint64 + InterfaceIndex uint32 + MaxReassemblySize uint32 + InterfaceIdentifier uint64 + MinRouterAdvertisementInterval uint32 + MaxRouterAdvertisementInterval uint32 + AdvertisingEnabled uint8 + ForwardingEnabled uint8 + WeakHostSend uint8 + WeakHostReceive uint8 + UseAutomaticMetric uint8 + UseNeighborUnreachabilityDetection uint8 + ManagedAddressConfigurationSupported uint8 + OtherStatefulConfigurationSupported uint8 + AdvertiseDefaultRoute uint8 + RouterDiscoveryBehavior uint32 + DadTransmits uint32 + BaseReachableTime uint32 + RetransmitTime uint32 + PathMtuDiscoveryTimeout uint32 + LinkLocalAddressBehavior uint32 + LinkLocalAddressTimeout uint32 + ZoneIndices [ScopeLevelCount]uint32 + SitePrefixLength uint32 + Metric uint32 + NlMtu uint32 + Connected uint8 + SupportsWakeUpPatterns uint8 + SupportsNeighborDiscovery uint8 + SupportsRouterDiscovery uint8 + ReachableTime uint32 + TransmitOffload uint32 + ReceiveOffload uint32 + DisableDefaultRoutes uint8 +} + // Console related constants used for the mode parameter to SetConsoleMode. See // https://docs.microsoft.com/en-us/windows/console/setconsolemode for details. diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 4c2e1bdc01ed38e77449c8e91766d02dc9940fce..01c0716c2c4e839cc1a0466642204f4e73b0236f 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -181,10 +181,15 @@ var ( procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree") procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute") procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute") + procCancelMibChangeNotify2 = modiphlpapi.NewProc("CancelMibChangeNotify2") procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo") procGetBestInterfaceEx = modiphlpapi.NewProc("GetBestInterfaceEx") procGetIfEntry = modiphlpapi.NewProc("GetIfEntry") + procGetIfEntry2Ex = modiphlpapi.NewProc("GetIfEntry2Ex") + procGetUnicastIpAddressEntry = modiphlpapi.NewProc("GetUnicastIpAddressEntry") + procNotifyIpInterfaceChange = modiphlpapi.NewProc("NotifyIpInterfaceChange") + procNotifyUnicastIpAddressChange = modiphlpapi.NewProc("NotifyUnicastIpAddressChange") procAddDllDirectory = modkernel32.NewProc("AddDllDirectory") procAssignProcessToJobObject = modkernel32.NewProc("AssignProcessToJobObject") procCancelIo = modkernel32.NewProc("CancelIo") @@ -275,8 +280,10 @@ var ( procGetMaximumProcessorCount = modkernel32.NewProc("GetMaximumProcessorCount") procGetModuleFileNameW = modkernel32.NewProc("GetModuleFileNameW") procGetModuleHandleExW = modkernel32.NewProc("GetModuleHandleExW") + procGetNamedPipeClientProcessId = modkernel32.NewProc("GetNamedPipeClientProcessId") procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") + procGetNamedPipeServerProcessId = modkernel32.NewProc("GetNamedPipeServerProcessId") procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult") procGetPriorityClass = modkernel32.NewProc("GetPriorityClass") procGetProcAddress = modkernel32.NewProc("GetProcAddress") @@ -1606,6 +1613,14 @@ func DwmSetWindowAttribute(hwnd HWND, attribute uint32, value unsafe.Pointer, si return } +func CancelMibChangeNotify2(notificationHandle Handle) (errcode error) { + r0, _, _ := syscall.Syscall(procCancelMibChangeNotify2.Addr(), 1, uintptr(notificationHandle), 0, 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0) if r0 != 0 { @@ -1638,6 +1653,46 @@ func GetIfEntry(pIfRow *MibIfRow) (errcode error) { return } +func GetIfEntry2Ex(level uint32, row *MibIfRow2) (errcode error) { + r0, _, _ := syscall.Syscall(procGetIfEntry2Ex.Addr(), 2, uintptr(level), uintptr(unsafe.Pointer(row)), 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func GetUnicastIpAddressEntry(row *MibUnicastIpAddressRow) (errcode error) { + r0, _, _ := syscall.Syscall(procGetUnicastIpAddressEntry.Addr(), 1, uintptr(unsafe.Pointer(row)), 0, 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func NotifyIpInterfaceChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) { + var _p0 uint32 + if initialNotification { + _p0 = 1 + } + r0, _, _ := syscall.Syscall6(procNotifyIpInterfaceChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + +func NotifyUnicastIpAddressChange(family uint16, callback uintptr, callerContext unsafe.Pointer, initialNotification bool, notificationHandle *Handle) (errcode error) { + var _p0 uint32 + if initialNotification { + _p0 = 1 + } + r0, _, _ := syscall.Syscall6(procNotifyUnicastIpAddressChange.Addr(), 5, uintptr(family), uintptr(callback), uintptr(callerContext), uintptr(_p0), uintptr(unsafe.Pointer(notificationHandle)), 0) + if r0 != 0 { + errcode = syscall.Errno(r0) + } + return +} + func AddDllDirectory(path *uint16) (cookie uintptr, err error) { r0, _, e1 := syscall.Syscall(procAddDllDirectory.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0) cookie = uintptr(r0) @@ -2393,6 +2448,14 @@ func GetModuleHandleEx(flags uint32, moduleName *uint16, module *Handle) (err er return } +func GetNamedPipeClientProcessId(pipe Handle, clientProcessID *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetNamedPipeClientProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(clientProcessID)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func GetNamedPipeHandleState(pipe Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) { r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0) if r1 == 0 { @@ -2409,6 +2472,14 @@ func GetNamedPipeInfo(pipe Handle, flags *uint32, outSize *uint32, inSize *uint3 return } +func GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetNamedPipeServerProcessId.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(serverProcessID)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) { var _p0 uint32 if wait { diff --git a/vendor/modules.txt b/vendor/modules.txt index a18d74a11d1bc3ea496f17ad25717317b2c625c7..e2327e66f5184c5e7dfaf2dd280a916bf8ef7405 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -67,15 +67,15 @@ github.com/go-logr/stdr # github.com/go-sql-driver/mysql v1.8.1 ## explicit; go 1.18 github.com/go-sql-driver/mysql -# github.com/go-webauthn/webauthn v0.10.2 -## explicit; go 1.21 +# github.com/go-webauthn/webauthn v0.12.2 +## explicit; go 1.23.0 github.com/go-webauthn/webauthn/metadata github.com/go-webauthn/webauthn/protocol github.com/go-webauthn/webauthn/protocol/webauthncbor github.com/go-webauthn/webauthn/protocol/webauthncose github.com/go-webauthn/webauthn/webauthn -# github.com/go-webauthn/x v0.1.9 -## explicit; go 1.21 +# github.com/go-webauthn/x v0.1.19 +## explicit; go 1.23.0 github.com/go-webauthn/x/revoke # github.com/gofrs/flock v0.12.1 ## explicit; go 1.21.0 @@ -90,8 +90,8 @@ github.com/google/go-cmp/cmp/internal/diff github.com/google/go-cmp/cmp/internal/flags github.com/google/go-cmp/cmp/internal/function github.com/google/go-cmp/cmp/internal/value -# github.com/google/go-tpm v0.9.0 -## explicit; go 1.20 +# github.com/google/go-tpm v0.9.3 +## explicit; go 1.22 github.com/google/go-tpm/legacy/tpm2 github.com/google/go-tpm/tpmutil github.com/google/go-tpm/tpmutil/tbs @@ -197,11 +197,10 @@ go.opentelemetry.io/otel/sdk/trace # go.opentelemetry.io/otel/trace v1.10.0 ## explicit; go 1.17 go.opentelemetry.io/otel/trace -# golang.org/x/crypto v0.27.0 -## explicit; go 1.20 +# golang.org/x/crypto v0.36.0 +## explicit; go 1.23.0 golang.org/x/crypto/argon2 golang.org/x/crypto/blake2b -golang.org/x/crypto/ed25519 golang.org/x/crypto/md4 golang.org/x/crypto/ocsp golang.org/x/crypto/pbkdf2 @@ -210,8 +209,8 @@ golang.org/x/crypto/scrypt ## explicit; go 1.18 golang.org/x/sync/errgroup golang.org/x/sync/singleflight -# golang.org/x/sys v0.25.0 -## explicit; go 1.18 +# golang.org/x/sys v0.31.0 +## explicit; go 1.23.0 golang.org/x/sys/cpu golang.org/x/sys/unix golang.org/x/sys/windows