func (wfe *WebFrontEndImpl) verifyPOST(request *http.Request, regCheck bool) ([]byte, *jose.JsonWebKey, core.Registration, error) { var reg core.Registration // Read body if request.Body == nil { return nil, nil, reg, errors.New("No body on POST") } body, err := ioutil.ReadAll(request.Body) if err != nil { return nil, nil, reg, err } // Parse as JWS parsedJws, err := jose.ParseSigned(string(body)) if err != nil { wfe.log.Debug(fmt.Sprintf("Parse error reading JWS: %v", err)) return nil, nil, reg, err } // Verify JWS // NOTE: It might seem insecure for the WFE to be trusted to verify // client requests, i.e., that the verification should be done at the // RA. However the WFE is the RA's only view of the outside world // *anyway*, so it could always lie about what key was used by faking // the signature itself. if len(parsedJws.Signatures) > 1 { wfe.log.Debug(fmt.Sprintf("Too many signatures on POST")) return nil, nil, reg, errors.New("Too many signatures on POST") } if len(parsedJws.Signatures) == 0 { wfe.log.Debug(fmt.Sprintf("POST not signed: %v", parsedJws)) return nil, nil, reg, errors.New("POST not signed") } // TODO: Look up key in registrations. // https://github.com/letsencrypt/boulder/issues/187 key := parsedJws.Signatures[0].Header.JsonWebKey payload, err := parsedJws.Verify(key) if err != nil { wfe.log.Debug(string(body)) wfe.log.Debug(fmt.Sprintf("JWS verification error: %v", err)) return nil, nil, reg, err } if regCheck { // Check that the key is assosiated with an actual account reg, err = wfe.SA.GetRegistrationByKey(*key) if err != nil { return nil, nil, reg, err } } // TODO Return JWS body return []byte(payload), key, reg, nil }
func (wfe *WebFrontEndImpl) verifyPOST(request *http.Request, regCheck bool) ([]byte, *jose.JsonWebKey, core.Registration, error) { var reg core.Registration // Read body if request.Body == nil { return nil, nil, reg, errors.New("No body on POST") } body, err := ioutil.ReadAll(request.Body) if err != nil { return nil, nil, reg, err } // Parse as JWS parsedJws, err := jose.ParseSigned(string(body)) if err != nil { wfe.log.Debug(fmt.Sprintf("Parse error reading JWS: %v", err)) return nil, nil, reg, err } // Verify JWS // NOTE: It might seem insecure for the WFE to be trusted to verify // client requests, i.e., that the verification should be done at the // RA. However the WFE is the RA's only view of the outside world // *anyway*, so it could always lie about what key was used by faking // the signature itself. if len(parsedJws.Signatures) > 1 { wfe.log.Debug(fmt.Sprintf("Too many signatures on POST")) return nil, nil, reg, errors.New("Too many signatures on POST") } if len(parsedJws.Signatures) == 0 { wfe.log.Debug(fmt.Sprintf("POST not signed: %v", parsedJws)) return nil, nil, reg, errors.New("POST not signed") } key := parsedJws.Signatures[0].Header.JsonWebKey payload, header, err := parsedJws.Verify(key) if err != nil { wfe.log.Debug(string(body)) wfe.log.Debug(fmt.Sprintf("JWS verification error: %v", err)) return nil, nil, reg, err } // Check that the request has a known anti-replay nonce // i.e., Nonce is in protected header and if err != nil || len(header.Nonce) == 0 { wfe.log.Debug("JWS has no anti-replay nonce") return nil, nil, reg, errors.New("JWS has no anti-replay nonce") } else if !wfe.nonceService.Valid(header.Nonce) { wfe.log.Debug(fmt.Sprintf("JWS has invalid anti-replay nonce: %s", header.Nonce)) return nil, nil, reg, errors.New("JWS has invalid anti-replay nonce") } reg, err = wfe.SA.GetRegistrationByKey(*key) if err != nil { // If we are requiring a valid registration, any failure to look up the // registration is an overall failure to verify. if regCheck { return nil, nil, reg, err } // Otherwise we just return an empty registration. The caller is expected // to use the returned key instead. reg = core.Registration{} } return []byte(payload), key, reg, nil }