Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(lint): import golangci.yaml from GoToSocial and fix violations #3

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Configuration file for golangci-lint linter.
# This will be automatically picked up when golangci-lint is invoked.
# For all config options, see https://golangci-lint.run/usage/configuration/#config-file
#
# For GoToSocial we mostly take the default linters, but we add a few to catch style issues as well.

# options for analysis running
run:
# include test files or not, default is true
tests: false
# timeout for analysis, e.g. 30s, 5m, default is 1m
timeout: 5m

linters:
# enable some extra linters, see here for the list: https://golangci-lint.run/usage/linters/
enable:
- gocritic
- gofmt
- goheader
- gosec
- nilerr
- revive

# https://golangci-lint.run/usage/linters/#linters-configuration
linters-settings:
# https://golangci-lint.run/usage/linters/#goheader
goheader:
template: |-
httpsig
Copyright (C) GoToSocial Authors [email protected]
Copyright (C) go-fed
SPDX-License-Identifier: BSD-3-Clause

BSD 3-Clause License

Copyright (c) 2018, go-fed
Copyright (c) 2024, GoToSocial Authors
All rights reserved.

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

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

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

* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# https://golangci-lint.run/usage/linters/#govet
govet:
disable:
- composites
# https://golangci-lint.run/usage/linters/#revive
revive:
rules:
# Enable most default rules.
# See: https://github.com/mgechev/revive/blob/master/defaults.toml
- name: blank-imports
- name: context-as-argument
- name: context-keys-type
- name: dot-imports
- name: error-naming
- name: error-return
- name: error-strings
- name: exported
- name: if-return
- name: increment-decrement
- name: var-naming
- name: var-declaration
- name: package-comments
- name: range
- name: receiver-naming
- name: time-naming
- name: unexported-return
- name: indent-error-flow
- name: errorf
- name: empty-block
- name: superfluous-else
- name: unreachable-code
# Disable below rules.
- name: redefines-builtin-id
disabled: true # This one is just annoying.
- name: unused-parameter
disabled: true # We often pass parameters to fulfil interfaces.
# https://golangci-lint.run/usage/linters/#staticcheck
staticcheck:
# Enable all checks, but disable SA1012: nil context passing.
# See: https://staticcheck.io/docs/configuration/options/#checks
checks: ["all", "-SA1012"]
84 changes: 59 additions & 25 deletions algorithms.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,49 @@
// httpsig
// Copyright (C) GoToSocial Authors [email protected]
// Copyright (C) go-fed
// SPDX-License-Identifier: BSD-3-Clause
//
// BSD 3-Clause License
//
// Copyright (c) 2018, go-fed
// Copyright (c) 2024, GoToSocial Authors
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package httpsig

import (
"crypto"
"crypto/ecdsa"
"crypto/hmac"
"crypto/rsa"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"crypto/subtle" // Use should trigger great care
"crypto/subtle"
"encoding/asn1"
"errors"
"fmt"
Expand All @@ -20,11 +55,11 @@ import (
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/blake2s"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/ripemd160"
"golang.org/x/crypto/sha3"
"golang.org/x/crypto/ssh"
)

//nolint:revive // Underscores aid legibility
const (
hmacPrefix = "hmac"
rsaPrefix = "rsa"
Expand Down Expand Up @@ -68,26 +103,23 @@ var hashToDef = map[crypto.Hash]struct {
// http://www.iana.org/assignments/signature-algorithms
//
// Note that the forbidden hashes have an invalid 'new' function.
crypto.MD4: {md4String, func(key []byte) (hash.Hash, error) { return nil, nil }},
crypto.MD5: {md5String, func(key []byte) (hash.Hash, error) { return nil, nil }},
// Temporarily enable SHA1 because of issue https://github.com/golang/go/issues/37278
crypto.SHA1: {sha1String, func(key []byte) (hash.Hash, error) { return sha1.New(), nil }},
milas marked this conversation as resolved.
Show resolved Hide resolved
crypto.MD4: {md4String, func(key []byte) (hash.Hash, error) { return nil, nil }},
crypto.MD5: {md5String, func(key []byte) (hash.Hash, error) { return nil, nil }},
crypto.SHA224: {sha224String, func(key []byte) (hash.Hash, error) { return sha256.New224(), nil }},
milas marked this conversation as resolved.
Show resolved Hide resolved
crypto.SHA256: {sha256String, func(key []byte) (hash.Hash, error) { return sha256.New(), nil }},
crypto.SHA384: {sha384String, func(key []byte) (hash.Hash, error) { return sha512.New384(), nil }},
crypto.SHA512: {sha512String, func(key []byte) (hash.Hash, error) { return sha512.New(), nil }},
crypto.MD5SHA1: {md5sha1String, func(key []byte) (hash.Hash, error) { return nil, nil }},
crypto.RIPEMD160: {ripemd160String, func(key []byte) (hash.Hash, error) { return ripemd160.New(), nil }},
milas marked this conversation as resolved.
Show resolved Hide resolved
crypto.SHA3_224: {sha3_224String, func(key []byte) (hash.Hash, error) { return sha3.New224(), nil }},
crypto.SHA3_256: {sha3_256String, func(key []byte) (hash.Hash, error) { return sha3.New256(), nil }},
crypto.SHA3_384: {sha3_384String, func(key []byte) (hash.Hash, error) { return sha3.New384(), nil }},
crypto.SHA3_512: {sha3_512String, func(key []byte) (hash.Hash, error) { return sha3.New512(), nil }},
crypto.SHA512_224: {sha512_224String, func(key []byte) (hash.Hash, error) { return sha512.New512_224(), nil }},
crypto.SHA512_256: {sha512_256String, func(key []byte) (hash.Hash, error) { return sha512.New512_256(), nil }},
crypto.BLAKE2s_256: {blake2s_256String, func(key []byte) (hash.Hash, error) { return blake2s.New256(key) }},
crypto.BLAKE2b_256: {blake2b_256String, func(key []byte) (hash.Hash, error) { return blake2b.New256(key) }},
crypto.BLAKE2b_384: {blake2b_384String, func(key []byte) (hash.Hash, error) { return blake2b.New384(key) }},
crypto.BLAKE2b_512: {blake2b_512String, func(key []byte) (hash.Hash, error) { return blake2b.New512(key) }},
crypto.BLAKE2s_256: {blake2s_256String, blake2s.New256},
crypto.BLAKE2b_256: {blake2b_256String, blake2b.New256},
crypto.BLAKE2b_384: {blake2b_384String, blake2b.New384},
crypto.BLAKE2b_512: {blake2b_512String, blake2b.New512},
}

var stringToHash map[string]crypto.Hash
Expand Down Expand Up @@ -148,6 +180,9 @@ type hmacAlgorithm struct {

func (h *hmacAlgorithm) Sign(sig, key []byte) ([]byte, error) {
hs, err := h.fn(key)
if err != nil {
return nil, err
}
if err = setSig(hs, sig); err != nil {
return nil, err
}
Expand Down Expand Up @@ -265,7 +300,7 @@ func (r *ed25519Algorithm) Verify(pub crypto.PublicKey, toHash, signature []byte
}

func (r *ed25519Algorithm) String() string {
return fmt.Sprintf("%s", ed25519Prefix)
return ed25519Prefix
}

var _ signer = &ecdsaAlgorithm{}
Expand Down Expand Up @@ -329,9 +364,8 @@ func (r *ecdsaAlgorithm) Verify(pub crypto.PublicKey, toHash, signature []byte)

if ecdsa.Verify(ecdsaK, r.Sum(nil), sig.R, sig.S) {
return nil
} else {
return errors.New("Invalid signature")
}
return errors.New("Invalid signature")
}

func (r *ecdsaAlgorithm) String() string {
Expand Down Expand Up @@ -371,7 +405,7 @@ func (r *blakeMacAlgorithm) Equal(sig, actualMAC, key []byte) (bool, error) {
}

func (r *blakeMacAlgorithm) String() string {
return fmt.Sprintf("%s", hashToDef[r.kind].name)
return hashToDef[r.kind].name
}

func setSig(a hash.Hash, b []byte) error {
Expand All @@ -386,9 +420,9 @@ func setSig(a hash.Hash, b []byte) error {
return nil
}

// IsSupportedHttpSigAlgorithm returns true if the string is supported by this
// IsSupportedAlgorithm returns true if the string is supported by this
// library, is not a hash known to be weak, and is supported by the hardware.
func IsSupportedHttpSigAlgorithm(algo string) bool {
func IsSupportedAlgorithm(algo string) bool {
a, err := isAvailable(algo)
return a && err == nil
}
Expand Down Expand Up @@ -460,16 +494,17 @@ func signerFromString(s string) (signer, error) {
s = strings.ToLower(s)
isEcdsa := false
isEd25519 := false
var algo string = ""
if strings.HasPrefix(s, ecdsaPrefix) {
var algo string
switch {
case strings.HasPrefix(s, ecdsaPrefix):
algo = strings.TrimPrefix(s, ecdsaPrefix+"-")
isEcdsa = true
} else if strings.HasPrefix(s, rsaPrefix) {
case strings.HasPrefix(s, rsaPrefix):
algo = strings.TrimPrefix(s, rsaPrefix+"-")
} else if strings.HasPrefix(s, ed25519Prefix) {
case strings.HasPrefix(s, ed25519Prefix):
isEd25519 = true
algo = "sha512"
} else {
default:
return nil, fmt.Errorf("no signer matching %q", s)
}
hash, cHash, err := newAlgorithm(algo, nil)
Expand Down Expand Up @@ -526,7 +561,6 @@ func macerFromString(s string) (macer, error) {
fn: hashFn,
kind: cHash,
}, nil
} else {
return nil, fmt.Errorf("no MACer matching %q", s)
}
return nil, fmt.Errorf("no MACer matching %q", s)
}
16 changes: 16 additions & 0 deletions algorithms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ func readFullFromCrypto(b []byte) error {
}

func TestIsAvailable(t *testing.T) {
//nolint:revive // Underscores aid legibility
const (
// Just because you can glue things together, doesn't mean they will
// work. The following options are not supported.
rsa_SHA3_224 Algorithm = rsaPrefix + "-" + sha3_224String
rsa_SHA3_256 Algorithm = rsaPrefix + "-" + sha3_256String
rsa_SHA3_384 Algorithm = rsaPrefix + "-" + sha3_384String
rsa_SHA3_512 Algorithm = rsaPrefix + "-" + sha3_512String
rsa_SHA512_224 Algorithm = rsaPrefix + "-" + sha512_224String
rsa_SHA512_256 Algorithm = rsaPrefix + "-" + sha512_256String
rsa_BLAKE2S_256 Algorithm = rsaPrefix + "-" + blake2s_256String
rsa_BLAKE2B_256 Algorithm = rsaPrefix + "-" + blake2b_256String
rsa_BLAKE2B_384 Algorithm = rsaPrefix + "-" + blake2b_384String
rsa_BLAKE2B_512 Algorithm = rsaPrefix + "-" + blake2b_512String
)

tests := []struct {
name string
algo string
Expand Down
Loading