From aafdb085b14560d391f8a5a190582a5bccddfe50 Mon Sep 17 00:00:00 2001 From: Johannes Schicktanz Date: Fri, 17 Jun 2022 09:37:17 +0200 Subject: [PATCH] configurable hash functions (#76) * make hash function configurable * removes NO_HASH. refactors hasher creation func --- bindings-go/apis/v2/signatures/const.go | 25 +++++++++++++++++++++++++ bindings-go/apis/v2/signatures/rsa.go | 25 +++++++++++++++---------- bindings-go/apis/v2/signatures/types.go | 24 ++++++++---------------- 3 files changed, 48 insertions(+), 26 deletions(-) create mode 100644 bindings-go/apis/v2/signatures/const.go diff --git a/bindings-go/apis/v2/signatures/const.go b/bindings-go/apis/v2/signatures/const.go new file mode 100644 index 00000000..307ecc34 --- /dev/null +++ b/bindings-go/apis/v2/signatures/const.go @@ -0,0 +1,25 @@ +// Copyright 2022 Copyright (c) 2022 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package signatures + +import "crypto" + +const ( + SHA256 = "sha256" +) + +var HashFunctions = map[string]crypto.Hash{ + SHA256: crypto.SHA256, +} diff --git a/bindings-go/apis/v2/signatures/rsa.go b/bindings-go/apis/v2/signatures/rsa.go index b3a2e9df..9c98f77e 100644 --- a/bindings-go/apis/v2/signatures/rsa.go +++ b/bindings-go/apis/v2/signatures/rsa.go @@ -65,15 +65,17 @@ func CreateRSASignerFromKeyFile(pathToPrivateKey, mediaType string) (*RSASigner, // Sign returns the signature for the data for the component descriptor. func (s RSASigner) Sign(componentDescriptor cdv2.ComponentDescriptor, digest cdv2.DigestSpec) (*cdv2.SignatureSpec, error) { + hashfunc, ok := HashFunctions[digest.HashAlgorithm] + if !ok { + return nil, fmt.Errorf("unknown hash algorithm %s", digest.HashAlgorithm) + } + decodedHash, err := hex.DecodeString(digest.Value) if err != nil { return nil, fmt.Errorf("unable to hex decode hash: %w", err) } - // ensure length of hash is correct - if len(decodedHash) != 32 { - return nil, fmt.Errorf("hash to sign has invalid length") - } - signature, err := rsa.SignPKCS1v15(rand.Reader, &s.privateKey, 0, decodedHash) + + signature, err := rsa.SignPKCS1v15(rand.Reader, &s.privateKey, hashfunc, decodedHash) if err != nil { return nil, fmt.Errorf("unable to sign hash: %w", err) } @@ -172,17 +174,20 @@ func (v RSAVerifier) Verify(componentDescriptor cdv2.ComponentDescriptor, signat return fmt.Errorf("invalid signature mediaType %s", signature.Signature.MediaType) } + hashfunc, ok := HashFunctions[signature.Digest.HashAlgorithm] + if !ok { + return fmt.Errorf("unknown hash algorithm %s", signature.Digest.HashAlgorithm) + } + decodedHash, err := hex.DecodeString(signature.Digest.Value) if err != nil { return fmt.Errorf("unable to hex decode hash %s: %w", signature.Digest.Value, err) } - // ensure length of hash is correct - if len(decodedHash) != 32 { - return fmt.Errorf("hash to verify has invalid length") - } - if err := rsa.VerifyPKCS1v15(&v.publicKey, 0, decodedHash, signatureBytes); err != nil { + + if err := rsa.VerifyPKCS1v15(&v.publicKey, hashfunc, decodedHash, signatureBytes); err != nil { return fmt.Errorf("unable to verify signature: %w", err) } + return nil } diff --git a/bindings-go/apis/v2/signatures/types.go b/bindings-go/apis/v2/signatures/types.go index ef38f79e..1d8b2081 100644 --- a/bindings-go/apis/v2/signatures/types.go +++ b/bindings-go/apis/v2/signatures/types.go @@ -16,10 +16,8 @@ package signatures import ( "context" - "crypto/sha256" "fmt" "hash" - "strings" cdv2 "github.com/gardener/component-spec/bindings-go/apis/v2" ) @@ -44,23 +42,17 @@ type Hasher struct { AlgorithmName string } -const SHA256 = "sha256" - // HasherForName creates a Hasher instance for the algorithmName. func HasherForName(algorithmName string) (*Hasher, error) { - switch strings.ToLower(algorithmName) { - case SHA256: - return &Hasher{ - HashFunction: sha256.New(), - AlgorithmName: SHA256, - }, nil - case strings.ToLower(cdv2.NoDigest): - return &Hasher{ - HashFunction: nil, - AlgorithmName: cdv2.NoDigest, - }, nil + hashfunc, ok := HashFunctions[algorithmName] + if !ok { + return nil, fmt.Errorf("hash algorithm %s not found/implemented", algorithmName) } - return nil, fmt.Errorf("hash algorithm %s not found/implemented", algorithmName) + + return &Hasher{ + HashFunction: hashfunc.New(), + AlgorithmName: algorithmName, + }, nil } type ResourceDigester interface {