Esempio n. 1
0
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
}
Esempio n. 2
0
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
}