Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / github.com / dgrijalva / jwt-go / ecdsa.go
1 package jwt
2
3 import (
4         "crypto"
5         "crypto/ecdsa"
6         "crypto/rand"
7         "errors"
8         "math/big"
9 )
10
11 var (
12         // Sadly this is missing from crypto/ecdsa compared to crypto/rsa
13         ErrECDSAVerification = errors.New("crypto/ecdsa: verification error")
14 )
15
16 // Implements the ECDSA family of signing methods signing methods
17 // Expects *ecdsa.PrivateKey for signing and *ecdsa.PublicKey for verification
18 type SigningMethodECDSA struct {
19         Name      string
20         Hash      crypto.Hash
21         KeySize   int
22         CurveBits int
23 }
24
25 // Specific instances for EC256 and company
26 var (
27         SigningMethodES256 *SigningMethodECDSA
28         SigningMethodES384 *SigningMethodECDSA
29         SigningMethodES512 *SigningMethodECDSA
30 )
31
32 func init() {
33         // ES256
34         SigningMethodES256 = &SigningMethodECDSA{"ES256", crypto.SHA256, 32, 256}
35         RegisterSigningMethod(SigningMethodES256.Alg(), func() SigningMethod {
36                 return SigningMethodES256
37         })
38
39         // ES384
40         SigningMethodES384 = &SigningMethodECDSA{"ES384", crypto.SHA384, 48, 384}
41         RegisterSigningMethod(SigningMethodES384.Alg(), func() SigningMethod {
42                 return SigningMethodES384
43         })
44
45         // ES512
46         SigningMethodES512 = &SigningMethodECDSA{"ES512", crypto.SHA512, 66, 521}
47         RegisterSigningMethod(SigningMethodES512.Alg(), func() SigningMethod {
48                 return SigningMethodES512
49         })
50 }
51
52 func (m *SigningMethodECDSA) Alg() string {
53         return m.Name
54 }
55
56 // Implements the Verify method from SigningMethod
57 // For this verify method, key must be an ecdsa.PublicKey struct
58 func (m *SigningMethodECDSA) Verify(signingString, signature string, key interface{}) error {
59         var err error
60
61         // Decode the signature
62         var sig []byte
63         if sig, err = DecodeSegment(signature); err != nil {
64                 return err
65         }
66
67         // Get the key
68         var ecdsaKey *ecdsa.PublicKey
69         switch k := key.(type) {
70         case *ecdsa.PublicKey:
71                 ecdsaKey = k
72         default:
73                 return ErrInvalidKeyType
74         }
75
76         if len(sig) != 2*m.KeySize {
77                 return ErrECDSAVerification
78         }
79
80         r := big.NewInt(0).SetBytes(sig[:m.KeySize])
81         s := big.NewInt(0).SetBytes(sig[m.KeySize:])
82
83         // Create hasher
84         if !m.Hash.Available() {
85                 return ErrHashUnavailable
86         }
87         hasher := m.Hash.New()
88         hasher.Write([]byte(signingString))
89
90         // Verify the signature
91         if verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus == true {
92                 return nil
93         } else {
94                 return ErrECDSAVerification
95         }
96 }
97
98 // Implements the Sign method from SigningMethod
99 // For this signing method, key must be an ecdsa.PrivateKey struct
100 func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) (string, error) {
101         // Get the key
102         var ecdsaKey *ecdsa.PrivateKey
103         switch k := key.(type) {
104         case *ecdsa.PrivateKey:
105                 ecdsaKey = k
106         default:
107                 return "", ErrInvalidKeyType
108         }
109
110         // Create the hasher
111         if !m.Hash.Available() {
112                 return "", ErrHashUnavailable
113         }
114
115         hasher := m.Hash.New()
116         hasher.Write([]byte(signingString))
117
118         // Sign the string and return r, s
119         if r, s, err := ecdsa.Sign(rand.Reader, ecdsaKey, hasher.Sum(nil)); err == nil {
120                 curveBits := ecdsaKey.Curve.Params().BitSize
121
122                 if m.CurveBits != curveBits {
123                         return "", ErrInvalidKey
124                 }
125
126                 keyBytes := curveBits / 8
127                 if curveBits%8 > 0 {
128                         keyBytes += 1
129                 }
130
131                 // We serialize the outpus (r and s) into big-endian byte arrays and pad
132                 // them with zeros on the left to make sure the sizes work out. Both arrays
133                 // must be keyBytes long, and the output must be 2*keyBytes long.
134                 rBytes := r.Bytes()
135                 rBytesPadded := make([]byte, keyBytes)
136                 copy(rBytesPadded[keyBytes-len(rBytes):], rBytes)
137
138                 sBytes := s.Bytes()
139                 sBytesPadded := make([]byte, keyBytes)
140                 copy(sBytesPadded[keyBytes-len(sBytes):], sBytes)
141
142                 out := append(rBytesPadded, sBytesPadded...)
143
144                 return EncodeSegment(out), nil
145         } else {
146                 return "", err
147         }
148 }