summaryrefslogtreecommitdiff
path: root/key_validator.go
diff options
context:
space:
mode:
Diffstat (limited to 'key_validator.go')
-rw-r--r--key_validator.go36
1 files changed, 19 insertions, 17 deletions
diff --git a/key_validator.go b/key_validator.go
index fe6eb7b..062d78c 100644
--- a/key_validator.go
+++ b/key_validator.go
@@ -4,11 +4,13 @@ import (
4 "crypto/rsa" 4 "crypto/rsa"
5 "crypto/x509" 5 "crypto/x509"
6 "encoding/pem" 6 "encoding/pem"
7 "fmt" 7 "github.com/pkg/errors"
8 "gopkg.in/square/go-jose.v2" 8 "gopkg.in/square/go-jose.v2"
9 "io/ioutil" 9 "io/ioutil"
10) 10)
11 11
12// TODO: CRL validation
13
12type KeyValidator interface { 14type KeyValidator interface {
13 Validate(jose.JSONWebKey) error 15 Validate(jose.JSONWebKey) error
14 LoadRootPEM(string) error 16 LoadRootPEM(string) error
@@ -31,17 +33,17 @@ func NewKeyValidator(subject string) KeyValidator {
31func (v *keyValidator) LoadRootPEM(filename string) error { 33func (v *keyValidator) LoadRootPEM(filename string) error {
32 pem_data, err := ioutil.ReadFile(filename) 34 pem_data, err := ioutil.ReadFile(filename)
33 if err != nil { 35 if err != nil {
34 return err 36 return errors.WithStack(err)
35 } 37 }
36 38
37 pem_block, _ := pem.Decode(pem_data) 39 pem_block, _ := pem.Decode(pem_data)
38 if pem_block == nil { 40 if pem_block == nil {
39 return fmt.Errorf("PEM decode failed") 41 return errors.Errorf("PEM decode failed")
40 } 42 }
41 43
42 cert, err := x509.ParseCertificate(pem_block.Bytes) 44 cert, err := x509.ParseCertificate(pem_block.Bytes)
43 if err != nil { 45 if err != nil {
44 return err 46 return errors.WithStack(err)
45 } 47 }
46 48
47 v.roots.AddCert(cert) 49 v.roots.AddCert(cert)
@@ -52,40 +54,40 @@ func (v *keyValidator) LoadRootPEM(filename string) error {
52func (v *keyValidator) Validate(key jose.JSONWebKey) error { 54func (v *keyValidator) Validate(key jose.JSONWebKey) error {
53 pk, ok := key.Key.(*rsa.PublicKey) 55 pk, ok := key.Key.(*rsa.PublicKey)
54 if !ok { 56 if !ok {
55 return fmt.Errorf("Key type is not RSA") 57 return errors.Errorf("Key type is not RSA")
56 } 58 }
57 59
58 if !v.algorithms.Contains(key.Algorithm) { 60 if !v.algorithms.Contains(key.Algorithm) {
59 return fmt.Errorf("Key algorithm is not supported") 61 return errors.Errorf("Key algorithm is not supported")
60 } 62 }
61 63
62 cert := key.Certificates[0] 64 cert := key.Certificates[0]
63 cpk, ok := cert.PublicKey.(*rsa.PublicKey) 65 cpk, ok := cert.PublicKey.(*rsa.PublicKey)
64 if !ok { 66 if !ok {
65 return fmt.Errorf("Public key is not RSA") 67 return errors.Errorf("Public key is not RSA")
66 } 68 }
67 69
68 if cpk.N.BitLen() < 2048 { 70 if cpk.N.BitLen() < 2048 {
69 return fmt.Errorf("Key length less than 2048 bits") 71 return errors.Errorf("Key length less than 2048 bits")
70 } 72 }
71 73
72 if cert.KeyUsage&x509.KeyUsageDigitalSignature != 1 { 74 if cert.KeyUsage&x509.KeyUsageDigitalSignature != 1 {
73 return fmt.Errorf("Certificate not valid for digital signatures") 75 return errors.Errorf("Certificate not valid for digital signatures")
74 } 76 }
75 77
76 err := v.validateCertificateChain(key.Certificates) 78 err := v.validateCertificateChain(key.Certificates)
77 if err != nil { 79 if err != nil {
78 return err 80 return errors.WithStack(err)
79 } 81 }
80 82
81 err = v.validateCertificateCRL(cert) 83 err = v.validateCertificateCRL(cert)
82 if err != nil { 84 if err != nil {
83 return err 85 return errors.WithStack(err)
84 } 86 }
85 87
86 err = v.validatePublicKeyInCertificate(pk, cpk) 88 err = v.validatePublicKeyInCertificate(pk, cpk)
87 if err != nil { 89 if err != nil {
88 return err 90 return errors.WithStack(err)
89 } 91 }
90 92
91 return nil 93 return nil
@@ -116,15 +118,15 @@ func (v *keyValidator) validateCertificateChain(chain []*x509.Certificate) error
116 118
117 chains, err := chain[0].Verify(vo) 119 chains, err := chain[0].Verify(vo)
118 if err != nil { 120 if err != nil {
119 return err 121 return errors.WithStack(err)
120 } 122 }
121 123
122 if len(chains) <= 0 { 124 if len(chains) <= 0 {
123 return fmt.Errorf("No valid certificate chains found") 125 return errors.Errorf("No valid certificate chains found")
124 } 126 }
125 127
126 if chain[0].Subject.CommonName != v.pkiSubject { 128 if chain[0].Subject.CommonName != v.pkiSubject {
127 return fmt.Errorf("Invalid certificate subject name") 129 return errors.Errorf("Invalid certificate subject name")
128 } 130 }
129 131
130 return nil 132 return nil
@@ -133,11 +135,11 @@ func (v *keyValidator) validateCertificateChain(chain []*x509.Certificate) error
133// validate first item of x5c matches n and e 135// validate first item of x5c matches n and e
134func (v *keyValidator) validatePublicKeyInCertificate(pk *rsa.PublicKey, cpk *rsa.PublicKey) error { 136func (v *keyValidator) validatePublicKeyInCertificate(pk *rsa.PublicKey, cpk *rsa.PublicKey) error {
135 if cpk.E != pk.E { 137 if cpk.E != pk.E {
136 return fmt.Errorf("E in key and E in cert do not match") 138 return errors.Errorf("E in key and E in cert do not match")
137 } 139 }
138 140
139 if pk.N.Cmp(cpk.N) != 0 { 141 if pk.N.Cmp(cpk.N) != 0 {
140 return fmt.Errorf("N in key and N in cert do not match") 142 return errors.Errorf("N in key and N in cert do not match")
141 } 143 }
142 144
143 return nil 145 return nil