(rw http.ResponseWriter, req *http.Request)
| 203 | } |
| 204 | |
| 205 | func (h *certRequestHandler) createSigningRequest(rw http.ResponseWriter, req *http.Request) { |
| 206 | err := req.ParseForm() |
| 207 | if err != nil { |
| 208 | http.Error(rw, fmt.Sprintf("%v", err), http.StatusBadRequest) |
| 209 | return |
| 210 | } |
| 211 | |
| 212 | cert, err := h.extractCertFromRequest(req) |
| 213 | if err != nil { |
| 214 | http.Error(rw, fmt.Sprintf("%v", err), http.StatusBadRequest) |
| 215 | return |
| 216 | } |
| 217 | |
| 218 | environment, ok := cert.Extensions["environment@cloudtools.github.io"] |
| 219 | if !ok || environment == "" { |
| 220 | http.Error(rw, "You forgot to send in the environment", http.StatusBadRequest) |
| 221 | return |
| 222 | } |
| 223 | |
| 224 | reason, ok := cert.Extensions["reason@cloudtools.github.io"] |
| 225 | if !ok || reason == "" { |
| 226 | http.Error(rw, "You forgot to send in a reason", http.StatusBadRequest) |
| 227 | return |
| 228 | } |
| 229 | |
| 230 | config, ok := h.Config[environment] |
| 231 | if !ok { |
| 232 | http.Error(rw, "Unknown environment.", http.StatusBadRequest) |
| 233 | return |
| 234 | } |
| 235 | |
| 236 | err = h.validateCert(cert, config.AuthorizedUsers) |
| 237 | if err != nil { |
| 238 | log.Printf("Invalid certificate signing request received from %s, ignoring", req.RemoteAddr) |
| 239 | http.Error(rw, fmt.Sprintf("%v", err), http.StatusBadRequest) |
| 240 | return |
| 241 | } |
| 242 | |
| 243 | // Ideally we put the critical options into the cert and let validateCert |
| 244 | // do the validation. However, this also checks the signature on the cert |
| 245 | // which would fail if we modified it prior to validation. So we validate |
| 246 | // by hand. |
| 247 | if len(config.CriticalOptions) > 0 { |
| 248 | for optionName, optionVal := range config.CriticalOptions { |
| 249 | cert.CriticalOptions[optionName] = optionVal |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | requestID := make([]byte, 8) |
| 254 | rand.Reader.Read(requestID) |
| 255 | requestIDStr := base32.StdEncoding.EncodeToString(requestID) |
| 256 | requestIDStr = strings.Replace(requestIDStr, "=", "", 10) |
| 257 | // the serial number is the same as the request id, just encoded differently. |
| 258 | var nextSerial uint64 |
| 259 | nextSerial = 0 |
| 260 | for _, byteVal := range requestID { |
| 261 | nextSerial <<= 8 |
| 262 | nextSerial |= uint64(byteVal) |
nothing calls this directly
no test coverage detected