(currentCA *x509.Certificate)
| 137 | } |
| 138 | |
| 139 | func (spec *Spec) validateStoredPKI(currentCA *x509.Certificate) error { |
| 140 | |
| 141 | existingCA, keyPair, err := spec.Storage.Load() |
| 142 | if err != nil { |
| 143 | return errors.WithMessage(err, "stored PKI is invalid") |
| 144 | } |
| 145 | spec.updateCAExpiry(currentCA.NotAfter) |
| 146 | |
| 147 | if existingCA != nil { |
| 148 | if !existingCA.Equal(currentCA) { |
| 149 | return errors.New("stored CA is out of date with new CA") |
| 150 | } |
| 151 | } |
| 152 | if !spec.Storage.WantsKeyPair() { |
| 153 | // nothing further to check |
| 154 | return nil |
| 155 | } |
| 156 | if keyPair.Leaf == nil { |
| 157 | // tls.LoadX509KeyPair doesn't retain leaf, force the reparse |
| 158 | leaf, err := x509.ParseCertificate(keyPair.Certificate[len(keyPair.Certificate)-1]) |
| 159 | if err != nil { |
| 160 | return errors.WithMessage(err, "failed parsing stored certificate") |
| 161 | } |
| 162 | keyPair.Leaf = leaf |
| 163 | } |
| 164 | // update internal metrics |
| 165 | spec.updateCertExpiry(keyPair.Leaf.NotAfter) |
| 166 | |
| 167 | err = CertificateChainVerify(currentCA, keyPair.Leaf, spec.KeyUsages) |
| 168 | if err != nil { |
| 169 | return errors.WithMessage(err, "stored cert failed CA check") |
| 170 | } |
| 171 | |
| 172 | // confirm that pkix is the same. This catches things like OU being changed; these are slices |
| 173 | // of slices and there isn't a usable equality check, thus the .String() usage. |
| 174 | if spec.Request.Name().String() != keyPair.Leaf.Subject.String() { |
| 175 | return fmt.Errorf("spec subject has changed: was %s, now is %s", keyPair.Leaf.Subject, spec.Request.Name()) |
| 176 | } |
| 177 | |
| 178 | if !CertificateMatchesHostname(spec.Request.Hosts, keyPair.Leaf) { |
| 179 | return errors.New("spec DNS name has changed") |
| 180 | } |
| 181 | |
| 182 | // validate that the cert isn't expired and is still valid. |
| 183 | now := time.Now() |
| 184 | if now.After(keyPair.Leaf.NotAfter) { |
| 185 | return fmt.Errorf("certificate already expired at %s", keyPair.Leaf.NotAfter) |
| 186 | } |
| 187 | now = now.Add(spec.tr.Before) |
| 188 | if now.After(keyPair.Leaf.NotAfter) { |
| 189 | return fmt.Errorf("certificate is within the renewal threshold of %s: %s", spec.tr.Before, keyPair.Leaf.NotAfter) |
| 190 | } |
| 191 | if keyPair.Leaf.NotBefore.After(now) { |
| 192 | // someone needs a better clock. |
| 193 | return fmt.Errorf("certificate isn't yet valid: %s", keyPair.Leaf.NotBefore) |
| 194 | } |
| 195 | return spec.validatePrivKey(keyPair.PrivateKey) |
| 196 | } |
no test coverage detected