(rw http.ResponseWriter, req *http.Request)
| 533 | } |
| 534 | |
| 535 | func (h *certRequestHandler) signOrRejectRequest(rw http.ResponseWriter, req *http.Request) { |
| 536 | requestID := mux.Vars(req)["requestID"] |
| 537 | h.stateMutex.RLock() |
| 538 | originalRequest, ok := h.state[requestID] |
| 539 | h.stateMutex.RUnlock() |
| 540 | if !ok { |
| 541 | http.Error(rw, "Unknown request id", http.StatusNotFound) |
| 542 | return |
| 543 | } |
| 544 | if originalRequest.certSigned { |
| 545 | http.Error(rw, "Request already signed.", http.StatusConflict) |
| 546 | return |
| 547 | } |
| 548 | if originalRequest.certRejected { |
| 549 | http.Error(rw, "Request already rejected.", http.StatusConflict) |
| 550 | return |
| 551 | } |
| 552 | |
| 553 | err := req.ParseForm() |
| 554 | if err != nil { |
| 555 | http.Error(rw, fmt.Sprintf("%v", err), http.StatusBadRequest) |
| 556 | return |
| 557 | } |
| 558 | |
| 559 | envConfig, ok := h.Config[originalRequest.environment] |
| 560 | if !ok { |
| 561 | http.Error(rw, "Original request found to have an invalid env. Weird.", http.StatusBadRequest) |
| 562 | return |
| 563 | } |
| 564 | |
| 565 | signedCert, err := h.extractCertFromRequest(req) |
| 566 | if err != nil { |
| 567 | log.Printf("Unable to extract certificate signing request from %s, ignoring", req.RemoteAddr) |
| 568 | http.Error(rw, fmt.Sprintf("%v", err), http.StatusBadRequest) |
| 569 | return |
| 570 | } |
| 571 | err = h.validateCert(signedCert, envConfig.AuthorizedSigners) |
| 572 | if err != nil { |
| 573 | log.Printf("Invalid certificate signing request received from %s, ignoring", req.RemoteAddr) |
| 574 | http.Error(rw, fmt.Sprintf("%v", err), http.StatusBadRequest) |
| 575 | return |
| 576 | } |
| 577 | |
| 578 | signerFp := ssh_ca_util.MakeFingerprint(signedCert.SignatureKey.Marshal()) |
| 579 | |
| 580 | // Verifying that the cert being posted to us here matches the one in the |
| 581 | // request. That is, that an attacker isn't using an old signature to sign a |
| 582 | // new/different request id |
| 583 | h.stateMutex.RLock() |
| 584 | requestedCert := h.state[requestID].request |
| 585 | h.stateMutex.RUnlock() |
| 586 | if !compareCerts(requestedCert, signedCert) { |
| 587 | log.Printf("Signature was valid, but cert didn't match from %s.", req.RemoteAddr) |
| 588 | log.Printf("Orig req: %#v\n", requestedCert) |
| 589 | log.Printf("Sign req: %#v\n", signedCert) |
| 590 | http.Error(rw, "Signature was valid, but cert didn't match.", http.StatusBadRequest) |
| 591 | return |
| 592 | } |
nothing calls this directly
no test coverage detected