-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathutils.go
More file actions
110 lines (96 loc) · 2.55 KB
/
utils.go
File metadata and controls
110 lines (96 loc) · 2.55 KB
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package httpsig
import (
"crypto"
"crypto/dsa"
"encoding/asn1"
"encoding/pem"
"errors"
"fmt"
"math/big"
"strings"
)
var validAlgorithms = map[string]bool{
"hmac": true,
"rsa": true,
"dsa": true,
"ecdsa": true,
}
var validHashAlgorithms = map[string]crypto.Hash{
"sha1": crypto.SHA1,
"sha256": crypto.SHA256,
"sha512": crypto.SHA512,
}
type hashAlgorithm struct {
sign string
hash crypto.Hash
}
type dsaSignature struct {
R, S *big.Int
}
func autoDetectAlgorithm(key string) (*hashAlgorithm, error) {
block, _ := pem.Decode([]byte(key))
if block == nil {
return nil, errors.New("Could not determine key format, key was not in PEM format")
}
switch block.Type {
case "RSA PRIVATE KEY":
return &hashAlgorithm{"rsa", crypto.SHA256}, nil
case "DSA PRIVATE KEY":
return &hashAlgorithm{"dsa", crypto.SHA256}, nil
case "EC PRIVATE KEY":
return &hashAlgorithm{"ecdsa", crypto.SHA256}, nil
default:
return nil, fmt.Errorf("Could not determine key format (pem block type '%s')", block.Type)
}
}
func validateAlgorithm(algorithm string) (*hashAlgorithm, error) {
alg := strings.Split(strings.ToLower(algorithm), "-")
if len(alg) != 2 {
return nil, fmt.Errorf("%s is not a valid algorithm", strings.ToUpper(algorithm))
}
if hash, ok := validHashAlgorithms[alg[1]]; ok {
if _, ok := validAlgorithms[alg[0]]; !ok {
return nil, fmt.Errorf("%s type keys are not supported", strings.ToUpper(alg[0]))
}
return &hashAlgorithm{alg[0], hash}, nil
}
return nil, fmt.Errorf("%s is not a supported hash algorithm", strings.ToUpper(alg[0]))
}
func (alg *hashAlgorithm) String() string {
return fmt.Sprintf("%s-%s", strings.ToLower(alg.sign), strings.ToLower(hashName(alg.hash)))
}
func hashName(hash crypto.Hash) string {
switch hash {
case crypto.SHA1:
return "SHA1"
case crypto.SHA256:
return "sha256"
case crypto.SHA512:
return "sha512"
}
return "unknown"
}
func calcHash(data string, hash crypto.Hash) []byte {
h := hash.New()
h.Write([]byte(data))
return h.Sum(nil)
}
type tempDsaKey struct {
E1, P, Q, G, Y, X *big.Int
}
// PEM DSA format doesn't parse using any of the built-in crypto methods, so this function parses a DSA private key from a PEM file
func getDsaKey(key string) (privateKey *dsa.PrivateKey, err error) {
block, _ := pem.Decode([]byte(key))
tmpKey := tempDsaKey{}
_, err = asn1.Unmarshal(block.Bytes, &tmpKey)
if err != nil {
return nil, err
}
privateKey = &dsa.PrivateKey{}
privateKey.P = tmpKey.P
privateKey.Q = tmpKey.Q
privateKey.G = tmpKey.G
privateKey.Y = tmpKey.Y
privateKey.X = tmpKey.X
return
}