Skip to content

Commit

Permalink
fix: handle all possible hash algorithms for verifying signature
Browse files Browse the repository at this point in the history
  • Loading branch information
mhrynenko committed Jan 6, 2025
1 parent f6b3821 commit 43a76ea
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 13 deletions.
55 changes: 47 additions & 8 deletions internal/service/api/handlers/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"crypto/sha256"
"encoding/asn1"
"encoding/hex"
"encoding/json"
"encoding/pem"
errors3 "errors"
"fmt"
Expand Down Expand Up @@ -44,13 +43,11 @@ func Register(w http.ResponseWriter, r *http.Request) {
return
}

rawReq, _ := json.Marshal(req)
log.WithField("sod", string(rawReq)).Debug("request started")

algorithmPair := types.AlgorithmPair{
DgHashAlgorithm: types.HashAlgorithmFromString(req.Data.Attributes.DocumentSod.HashAlgorithm),
SignedAttrHashAlg: types.HashAlgorithmFromString(req.Data.Attributes.DocumentSod.HashAlgorithm),
SignatureAlgorithm: types.SignatureAlgorithmFromString(req.Data.Attributes.DocumentSod.SignatureAlgorithm),
DgHashAlgorithm: types.HashAlgorithmFromString(req.Data.Attributes.DocumentSod.HashAlgorithm),
SignedAttrHashAlg: types.HashAlgorithmFromString(req.Data.Attributes.DocumentSod.HashAlgorithm),
SignatureDigestHashAlg: types.HashAlgorithmFromString(req.Data.Attributes.DocumentSod.HashAlgorithm),
SignatureAlgorithm: types.SignatureAlgorithmFromString(req.Data.Attributes.DocumentSod.SignatureAlgorithm),
}

documentSOD := data.DocumentSOD{
Expand Down Expand Up @@ -484,7 +481,7 @@ func verifySignature(
signedAttributes []byte,
algorithmPair types.AlgorithmPair,
) ([]byte, error) {
h := types.GeneralHash(algorithmPair.SignedAttrHashAlg)
h := types.GeneralHash(algorithmPair.SignatureDigestHashAlg)
h.Write(signedAttributes)
d := h.Sum(nil)

Expand All @@ -495,6 +492,48 @@ func verifySignature(
return d, nil
}

func verifySignatureIterated(
signature []byte,
cert *x509.Certificate,
signedAttributes []byte,
algorithmPair types.AlgorithmPair,
) ([]byte, error) {
// Default flow to verify signature
errs := make([]error, 0, len(types.HashAlgorithmMap))
digest, err := verifySignature(signature, cert, signedAttributes, algorithmPair)
if err == nil {
return digest, nil
}

errs = append(errs, errors.From(err, logan.F{
"hash_alg": algorithmPair.SignatureDigestHashAlg.String(),
"signature": algorithmPair.SignatureAlgorithm.String(),
}))

// Workaround to handle signature digest hash algorithm different from specified in request
for name, algorithm := range types.HashAlgorithmMap {
if algorithm == algorithmPair.SignatureDigestHashAlg {
continue
}

algo := algorithmPair
algo.SignatureDigestHashAlg = algorithm
digest, err = verifySignature(signature, cert, signedAttributes, algo)
if err == nil {
// TODO use logger
fmt.Printf("found suitable digest hash algorithm for signature %s instead %s\n", name, algorithmPair.SignatureDigestHashAlg.String())
return digest, nil
}

errs = append(errs, errors.From(err, logan.F{
"hash_alg": name,
"signature": algorithmPair.SignatureAlgorithm.String(),
}))
}

return nil, errors3.Join(errs...)
}

func validateCert(cert *x509.Certificate, masterCerts *x509.CertPool, disableTimeChecks, disableNameChecks bool) error {
foundCerts, err := cert.Verify(x509.VerifyOptions{
Roots: masterCerts,
Expand Down
6 changes: 3 additions & 3 deletions internal/types/enums.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const (
SHA512
)

var hashAlgorithmMap = map[string]HashAlgorithm{
var HashAlgorithmMap = map[string]HashAlgorithm{
"SHA1": SHA1,
"SHA224": SHA224,
"SHA256": SHA256,
Expand Down Expand Up @@ -46,7 +46,7 @@ func (h HashAlgorithm) String() string {
}

func HashAlgorithmFromString(alg string) HashAlgorithm {
h, ok := hashAlgorithmMap[strings.ToUpper(alg)]
h, ok := HashAlgorithmMap[strings.ToUpper(alg)]
if !ok {
return HashAlgorithm(0)
}
Expand All @@ -62,7 +62,7 @@ func HashAlgorithmFromSize(size int) HashAlgorithm {
}

func IsValidHashAlgorithm(alg string) (HashAlgorithm, bool) {
h, ok := hashAlgorithmMap[alg]
h, ok := HashAlgorithmMap[alg]
return h, ok
}

Expand Down
5 changes: 3 additions & 2 deletions internal/types/signature_algorithm.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ func (e ErrInvalidPublicKey) Error() string {

// AlgorithmPair defines a hash and signature algorithm combination.
type AlgorithmPair struct {
DgHashAlgorithm HashAlgorithm
SignedAttrHashAlg HashAlgorithm
DgHashAlgorithm HashAlgorithm
SignedAttrHashAlg HashAlgorithm
SignatureDigestHashAlg HashAlgorithm
SignatureAlgorithm
}

Expand Down

0 comments on commit 43a76ea

Please sign in to comment.