-
Notifications
You must be signed in to change notification settings - Fork 394
/
utils.go
96 lines (78 loc) · 2.61 KB
/
utils.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
86
87
88
89
90
91
92
93
94
95
96
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package peertls
// Many cryptography standards use ASN.1 to define their data structures,
// and Distinguished Encoding Rules (DER) to serialize those structures.
// Because DER produces binary output, it can be challenging to transmit
// the resulting files through systems, like electronic mail, that only
// support ASCII. The PEM format solves this problem by encoding the
// binary data using base64.
// (see https://en.wikipedia.org/wiki/Privacy-enhanced_Electronic_Mail)
import (
"crypto"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
"math/big"
"github.com/zeebo/errs"
"storj.io/storj/pkg/pkcrypto"
)
// NonTemporaryError is an error with a `Temporary` method which always returns false.
// It is intended for use with grpc.
//
// (see https://godoc.org/google.golang.org/grpc#WithDialer
// and https://godoc.org/google.golang.org/grpc#FailOnNonTempDialError).
type NonTemporaryError struct{ error }
// NewNonTemporaryError returns a new temporary error for use with grpc.
func NewNonTemporaryError(err error) NonTemporaryError {
return NonTemporaryError{
error: errs.Wrap(err),
}
}
// DoubleSHA256PublicKey returns the hash of the hash of (double-hash, SHA226)
// the binary format of the given public key.
func DoubleSHA256PublicKey(k crypto.PublicKey) ([sha256.Size]byte, error) {
kb, err := x509.MarshalPKIXPublicKey(k)
if err != nil {
return [sha256.Size]byte{}, err
}
mid := sha256.Sum256(kb)
end := sha256.Sum256(mid[:])
return end, nil
}
// Temporary returns false to indicate that is is a non-temporary error
func (nte NonTemporaryError) Temporary() bool {
return false
}
// Err returns the underlying error
func (nte NonTemporaryError) Err() error {
return nte.error
}
func verifyChainSignatures(certs []*x509.Certificate) error {
for i, cert := range certs {
j := len(certs)
if i+1 < j {
err := verifyCertSignature(certs[i+1], cert)
if err != nil {
return ErrVerifyCertificateChain.Wrap(err)
}
continue
}
err := verifyCertSignature(cert, cert)
if err != nil {
return ErrVerifyCertificateChain.Wrap(err)
}
}
return nil
}
func verifyCertSignature(parentCert, childCert *x509.Certificate) error {
return pkcrypto.HashAndVerifySignature(parentCert.PublicKey, childCert.RawTBSCertificate, childCert.Signature)
}
func newSerialNumber() (*big.Int, error) {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return nil, errs.New("failed to generateServerTls serial number: %s", err.Error())
}
return serialNumber, nil
}