|
1 | 1 | package authority
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "crypto/x509" |
| 5 | + "encoding/asn1" |
4 | 6 | "net/http"
|
5 | 7 | "time"
|
6 | 8 |
|
@@ -117,3 +119,54 @@ func (a *Authority) Authorize(ott string) ([]interface{}, error) {
|
117 | 119 |
|
118 | 120 | return signOps, nil
|
119 | 121 | }
|
| 122 | + |
| 123 | +// authorizeRenewal tries to locate the step provisioner extension, and checks |
| 124 | +// if for the configured provisioner, the renewal is enabled or not. If the |
| 125 | +// extra extension cannot be found, authorize the renewal by default. |
| 126 | +// |
| 127 | +// TODO(mariano): should we authorize by default? |
| 128 | +func (a *Authority) authorizeRenewal(crt *x509.Certificate) error { |
| 129 | + errContext := map[string]interface{}{"serialNumber": crt.SerialNumber.String()} |
| 130 | + for _, e := range crt.Extensions { |
| 131 | + if e.Id.Equal(stepOIDProvisioner) { |
| 132 | + var provisioner stepProvisionerASN1 |
| 133 | + if _, err := asn1.Unmarshal(e.Value, &provisioner); err != nil { |
| 134 | + return &apiError{ |
| 135 | + err: errors.Wrap(err, "error decoding step provisioner extension"), |
| 136 | + code: http.StatusInternalServerError, |
| 137 | + context: errContext, |
| 138 | + } |
| 139 | + } |
| 140 | + |
| 141 | + // Look for the provisioner, if it cannot be found, renewal will not |
| 142 | + // be authorized. |
| 143 | + pid := string(provisioner.Name) + ":" + string(provisioner.CredentialID) |
| 144 | + val, ok := a.provisionerIDIndex.Load(pid) |
| 145 | + if !ok { |
| 146 | + return &apiError{ |
| 147 | + err: errors.Errorf("not found: provisioner %s", pid), |
| 148 | + code: http.StatusUnauthorized, |
| 149 | + context: errContext, |
| 150 | + } |
| 151 | + } |
| 152 | + p, ok := val.(*Provisioner) |
| 153 | + if !ok { |
| 154 | + return &apiError{ |
| 155 | + err: errors.Errorf("invalid type: provisioner %s, type %T", pid, val), |
| 156 | + code: http.StatusInternalServerError, |
| 157 | + context: errContext, |
| 158 | + } |
| 159 | + } |
| 160 | + if p.Claims.IsDisableRenewal() { |
| 161 | + return &apiError{ |
| 162 | + err: errors.Errorf("renew disabled: provisioner %s", pid), |
| 163 | + code: http.StatusUnauthorized, |
| 164 | + context: errContext, |
| 165 | + } |
| 166 | + } |
| 167 | + return nil |
| 168 | + } |
| 169 | + } |
| 170 | + |
| 171 | + return nil |
| 172 | +} |
0 commit comments