-
Notifications
You must be signed in to change notification settings - Fork 291
/
signature.go
85 lines (73 loc) · 2.14 KB
/
signature.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//
// (C) Copyright 2019-2021 Intel Corporation.
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
package security
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha512"
"io"
"github.com/pkg/errors"
)
// UnsupportedKeyError is a structured error used to indicate that the PublicKey
// or PrivateKey interface passed in represents a key type we do not support.
type UnsupportedKeyError struct{}
// Error is the implementation of the error interface.
func (err *UnsupportedKeyError) Error() string {
return "key contains an unsupported key type"
}
// TokenSigner serves to encapsulate the functionality needed
// to sign and verify auth token signatures.
type TokenSigner struct {
randPool io.Reader
}
// DefaultTokenSigner creates a TokenSigner with an instantiated entropy pool.
func DefaultTokenSigner() *TokenSigner {
return &TokenSigner{
randPool: rand.Reader,
}
}
// Hash returns the SHA-512 hash of the byte array passed in.
func (s *TokenSigner) Hash(data []byte) ([]byte, error) {
hash := sha512.New()
if _, err := hash.Write(data); err != nil {
return nil, errors.New("hash failed to write")
}
return hash.Sum(nil), nil
}
// Sign takes an unhashed set of bytes and hashes and signs the result with the
// key passed in.
func (s *TokenSigner) Sign(key crypto.PrivateKey, data []byte) ([]byte, error) {
digest, err := s.Hash(data)
if err != nil {
return nil, err
}
if s.randPool == nil {
s.randPool = rand.Reader
}
switch signingKey := key.(type) {
// TODO: Support key types other than RSA
case *rsa.PrivateKey:
return rsa.SignPSS(s.randPool, signingKey, crypto.SHA512, digest, nil)
default:
return nil, &UnsupportedKeyError{}
}
}
// Verify takes an unhashed set of bytes and hashes the data and verifies the
// signature against the hash and the publickey passed in.
func (s *TokenSigner) Verify(key crypto.PublicKey, data []byte, sig []byte) error {
digest, err := s.Hash(data)
if err != nil {
return err
}
switch signingKey := key.(type) {
// TODO: Support key types other than RSA
case *rsa.PublicKey:
return rsa.VerifyPSS(signingKey, crypto.SHA512, digest, sig, nil)
default:
return &UnsupportedKeyError{}
}
}