本文整理汇总了Golang中github.com/letsencrypt/boulder/core.ProblemDetailsForError函数的典型用法代码示例。如果您正苦于以下问题:Golang ProblemDetailsForError函数的具体用法?Golang ProblemDetailsForError怎么用?Golang ProblemDetailsForError使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了ProblemDetailsForError函数的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: NewAuthorization
// NewAuthorization is used by clients to submit a new ID Authorization
func (wfe *WebFrontEndImpl) NewAuthorization(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
body, _, currReg, prob := wfe.verifyPOST(ctx, logEvent, request, true, core.ResourceNewAuthz)
addRequesterHeader(response, logEvent.Requester)
if prob != nil {
// verifyPOST handles its own setting of logEvent.Errors
wfe.sendError(response, logEvent, prob, nil)
return
}
// Any version of the agreement is acceptable here. Version match is enforced in
// wfe.Registration when agreeing the first time. Agreement updates happen
// by mailing subscribers and don't require a registration update.
if currReg.Agreement == "" {
wfe.sendError(response, logEvent, probs.Unauthorized("Must agree to subscriber agreement before any further actions"), nil)
return
}
var init core.Authorization
if err := json.Unmarshal(body, &init); err != nil {
logEvent.AddError("unable to JSON unmarshal Authorization: %s", err)
wfe.sendError(response, logEvent, probs.Malformed("Error unmarshaling JSON"), err)
return
}
logEvent.Extra["Identifier"] = init.Identifier
// Create new authz and return
authz, err := wfe.RA.NewAuthorization(ctx, init, currReg.ID)
if err != nil {
logEvent.AddError("unable to create new authz: %s", err)
wfe.sendError(response, logEvent, core.ProblemDetailsForError(err, "Error creating new authz"), err)
return
}
logEvent.Extra["AuthzID"] = authz.ID
// Make a URL for this authz, then blow away the ID and RegID before serializing
authzURL := wfe.relativeEndpoint(request, authzPath+string(authz.ID))
wfe.prepAuthorizationForDisplay(request, &authz)
responseBody, err := marshalIndent(authz)
if err != nil {
// ServerInternal because we generated the authz, it should be OK
wfe.sendError(response, logEvent, probs.ServerInternal("Error marshaling authz"), err)
return
}
response.Header().Add("Location", authzURL)
response.Header().Add("Link", link(wfe.relativeEndpoint(request, newCertPath), "next"))
response.Header().Set("Content-Type", "application/json")
response.WriteHeader(http.StatusCreated)
if _, err = response.Write(responseBody); err != nil {
logEvent.AddError(err.Error())
wfe.log.Warning(fmt.Sprintf("Could not write response: %s", err))
}
}
开发者ID:MTRNord,项目名称:boulder-freifunk_support,代码行数:53,代码来源:wfe.go
示例2: Registration
// Registration is used by a client to submit an update to their registration.
func (wfe *WebFrontEndImpl) Registration(logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
body, _, currReg, prob := wfe.verifyPOST(logEvent, request, true, core.ResourceRegistration)
if prob != nil {
// verifyPOST handles its own setting of logEvent.Errors
wfe.sendError(response, logEvent, prob, nil)
return
}
// Requests to this handler should have a path that leads to a known
// registration
idStr := parseIDFromPath(request.URL.Path)
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
logEvent.AddError("registration ID must be an integer, was %#v", idStr)
wfe.sendError(response, logEvent, probs.Malformed("Registration ID must be an integer"), err)
return
} else if id <= 0 {
msg := fmt.Sprintf("Registration ID must be a positive non-zero integer, was %d", id)
logEvent.AddError(msg)
wfe.sendError(response, logEvent, probs.Malformed(msg), nil)
return
} else if id != currReg.ID {
logEvent.AddError("Request signing key did not match registration key: %d != %d", id, currReg.ID)
wfe.sendError(response, logEvent, probs.Unauthorized("Request signing key did not match registration key"), nil)
return
}
var update core.Registration
err = json.Unmarshal(body, &update)
if err != nil {
logEvent.AddError("unable to JSON parse registration: %s", err)
wfe.sendError(response, logEvent, probs.Malformed("Error unmarshaling registration"), err)
return
}
if len(update.Agreement) > 0 && update.Agreement != wfe.SubscriberAgreementURL {
msg := fmt.Sprintf("Provided agreement URL [%s] does not match current agreement URL [%s]", update.Agreement, wfe.SubscriberAgreementURL)
logEvent.AddError(msg)
wfe.sendError(response, logEvent, probs.Malformed(msg), nil)
return
}
// Registration objects contain a JWK object, which must be non-nil. We know
// the key of the updated registration object is going to be the same as the
// key of the current one, so we set it here. This ensures we can cleanly
// serialize the update as JSON to send via AMQP to the RA.
update.Key = currReg.Key
// Ask the RA to update this authorization.
updatedReg, err := wfe.RA.UpdateRegistration(currReg, update)
if err != nil {
logEvent.AddError("unable to update registration: %s", err)
wfe.sendError(response, logEvent, core.ProblemDetailsForError(err, "Unable to update registration"), err)
return
}
jsonReply, err := json.Marshal(updatedReg)
if err != nil {
// ServerInternal because we just generated the reg, it should be OK
logEvent.AddError("unable to marshal updated registration: %s", err)
wfe.sendError(response, logEvent, probs.ServerInternal("Failed to marshal registration"), err)
return
}
response.Header().Set("Content-Type", "application/json")
response.Header().Add("Link", link(wfe.NewAuthz, "next"))
if len(wfe.SubscriberAgreementURL) > 0 {
response.Header().Add("Link", link(wfe.SubscriberAgreementURL, "terms-of-service"))
}
response.WriteHeader(http.StatusAccepted)
response.Write(jsonReply)
}
开发者ID:dash1291,项目名称:boulder,代码行数:73,代码来源:web-front-end.go
示例3: postChallenge
func (wfe *WebFrontEndImpl) postChallenge(
response http.ResponseWriter,
request *http.Request,
authz core.Authorization,
challengeIndex int,
logEvent *requestEvent) {
body, _, currReg, prob := wfe.verifyPOST(logEvent, request, true, core.ResourceChallenge)
if prob != nil {
// verifyPOST handles its own setting of logEvent.Errors
wfe.sendError(response, logEvent, prob, nil)
return
}
// Any version of the agreement is acceptable here. Version match is enforced in
// wfe.Registration when agreeing the first time. Agreement updates happen
// by mailing subscribers and don't require a registration update.
if currReg.Agreement == "" {
wfe.sendError(response, logEvent, probs.Unauthorized("Registration didn't agree to subscriber agreement before any further actions"), nil)
return
}
// Check that the registration ID matching the key used matches
// the registration ID on the authz object
if currReg.ID != authz.RegistrationID {
logEvent.AddError("User registration id: %d != Authorization registration id: %v", currReg.ID, authz.RegistrationID)
wfe.sendError(response,
logEvent,
probs.Unauthorized("User registration ID doesn't match registration ID in authorization"),
nil,
)
return
}
var challengeUpdate core.Challenge
if err := json.Unmarshal(body, &challengeUpdate); err != nil {
logEvent.AddError("error JSON unmarshalling challenge response: %s", err)
wfe.sendError(response, logEvent, probs.Malformed("Error unmarshaling challenge response"), err)
return
}
// Ask the RA to update this authorization
updatedAuthorization, err := wfe.RA.UpdateAuthorization(authz, challengeIndex, challengeUpdate)
if err != nil {
logEvent.AddError("unable to update challenge: %s", err)
wfe.sendError(response, logEvent, core.ProblemDetailsForError(err, "Unable to update challenge"), err)
return
}
// assumption: UpdateAuthorization does not modify order of challenges
challenge := updatedAuthorization.Challenges[challengeIndex]
wfe.prepChallengeForDisplay(authz, &challenge)
jsonReply, err := json.Marshal(challenge)
if err != nil {
// ServerInternal because we made the challenges, they should be OK
logEvent.AddError("failed to marshal challenge: %s", err)
wfe.sendError(response, logEvent, probs.ServerInternal("Failed to marshal challenge"), err)
return
}
authzURL := wfe.AuthzBase + string(authz.ID)
response.Header().Add("Location", challenge.URI)
response.Header().Set("Content-Type", "application/json")
response.Header().Add("Link", link(authzURL, "up"))
response.WriteHeader(http.StatusAccepted)
if _, err = response.Write(jsonReply); err != nil {
logEvent.AddError(err.Error())
wfe.log.Warning(fmt.Sprintf("Could not write response: %s", err))
return
}
}
开发者ID:dash1291,项目名称:boulder,代码行数:69,代码来源:web-front-end.go
示例4: NewCertificate
// NewCertificate is used by clients to request the issuance of a cert for an
// authorized identifier.
func (wfe *WebFrontEndImpl) NewCertificate(logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
body, _, reg, prob := wfe.verifyPOST(logEvent, request, true, core.ResourceNewCert)
if prob != nil {
// verifyPOST handles its own setting of logEvent.Errors
wfe.sendError(response, logEvent, prob, nil)
return
}
// Any version of the agreement is acceptable here. Version match is enforced in
// wfe.Registration when agreeing the first time. Agreement updates happen
// by mailing subscribers and don't require a registration update.
if reg.Agreement == "" {
wfe.sendError(response, logEvent, probs.Unauthorized("Must agree to subscriber agreement before any further actions"), nil)
return
}
var certificateRequest core.CertificateRequest
if err := json.Unmarshal(body, &certificateRequest); err != nil {
logEvent.AddError("unable to JSON unmarshal CertificateRequest: %s", err)
wfe.sendError(response, logEvent, probs.Malformed("Error unmarshaling certificate request"), err)
return
}
wfe.logCsr(request, certificateRequest, reg)
// Check that the key in the CSR is good. This will also be checked in the CA
// component, but we want to discard CSRs with bad keys as early as possible
// because (a) it's an easy check and we can save unnecessary requests and
// bytes on the wire, and (b) the CA logs all rejections as audit events, but
// a bad key from the client is just a malformed request and doesn't need to
// be audited.
if err := wfe.keyPolicy.GoodKey(certificateRequest.CSR.PublicKey); err != nil {
logEvent.AddError("CSR public key failed GoodKey: %s", err)
wfe.sendError(response, logEvent, probs.Malformed("Invalid key in certificate request :: %s", err), err)
return
}
logEvent.Extra["CSRDNSNames"] = certificateRequest.CSR.DNSNames
logEvent.Extra["CSREmailAddresses"] = certificateRequest.CSR.EmailAddresses
logEvent.Extra["CSRIPAddresses"] = certificateRequest.CSR.IPAddresses
// Create new certificate and return
// TODO IMPORTANT: The RA trusts the WFE to provide the correct key. If the
// WFE is compromised, *and* the attacker knows the public key of an account
// authorized for target site, they could cause issuance for that site by
// lying to the RA. We should probably pass a copy of the whole rquest to the
// RA for secondary validation.
cert, err := wfe.RA.NewCertificate(certificateRequest, reg.ID)
if err != nil {
logEvent.AddError("unable to create new cert: %s", err)
wfe.sendError(response, logEvent, core.ProblemDetailsForError(err, "Error creating new cert"), err)
return
}
// Make a URL for this certificate.
// We use only the sequential part of the serial number, because it should
// uniquely identify the certificate, and this makes it easy for anybody to
// enumerate and mirror our certificates.
parsedCertificate, err := x509.ParseCertificate([]byte(cert.DER))
if err != nil {
logEvent.AddError("unable to parse certificate: %s", err)
wfe.sendError(response, logEvent, probs.Malformed("Unable to parse certificate"), err)
return
}
serial := parsedCertificate.SerialNumber
certURL := wfe.CertBase + core.SerialToString(serial)
// TODO Content negotiation
response.Header().Add("Location", certURL)
response.Header().Add("Link", link(wfe.BaseURL+IssuerPath, "up"))
response.Header().Set("Content-Type", "application/pkix-cert")
response.WriteHeader(http.StatusCreated)
if _, err = response.Write(cert.DER); err != nil {
logEvent.AddError(err.Error())
wfe.log.Warning(fmt.Sprintf("Could not write response: %s", err))
}
}
开发者ID:dash1291,项目名称:boulder,代码行数:75,代码来源:web-front-end.go
示例5: RevokeCertificate
// RevokeCertificate is used by clients to request the revocation of a cert.
func (wfe *WebFrontEndImpl) RevokeCertificate(logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
// We don't ask verifyPOST to verify there is a corresponding registration,
// because anyone with the right private key can revoke a certificate.
body, requestKey, registration, prob := wfe.verifyPOST(logEvent, request, false, core.ResourceRevokeCert)
if prob != nil {
// verifyPOST handles its own setting of logEvent.Errors
wfe.sendError(response, logEvent, prob, nil)
return
}
type RevokeRequest struct {
CertificateDER core.JSONBuffer `json:"certificate"`
}
var revokeRequest RevokeRequest
if err := json.Unmarshal(body, &revokeRequest); err != nil {
logEvent.AddError(fmt.Sprintf("Couldn't unmarshal in revoke request %s", string(body)))
wfe.sendError(response, logEvent, probs.Malformed("Unable to JSON parse revoke request"), err)
return
}
providedCert, err := x509.ParseCertificate(revokeRequest.CertificateDER)
if err != nil {
logEvent.AddError("unable to parse revoke certificate DER: %s", err)
wfe.sendError(response, logEvent, probs.Malformed("Unable to parse certificate DER"), err)
return
}
serial := core.SerialToString(providedCert.SerialNumber)
logEvent.Extra["ProvidedCertificateSerial"] = serial
cert, err := wfe.SA.GetCertificate(serial)
// TODO(#991): handle db errors better
if err != nil || !bytes.Equal(cert.DER, revokeRequest.CertificateDER) {
wfe.sendError(response, logEvent, probs.NotFound("No such certificate"), err)
return
}
parsedCertificate, err := x509.ParseCertificate(cert.DER)
if err != nil {
// InternalServerError because this is a failure to decode from our DB.
wfe.sendError(response, logEvent, probs.ServerInternal("invalid parse of stored certificate"), err)
return
}
logEvent.Extra["RetrievedCertificateSerial"] = core.SerialToString(parsedCertificate.SerialNumber)
logEvent.Extra["RetrievedCertificateDNSNames"] = parsedCertificate.DNSNames
logEvent.Extra["RetrievedCertificateEmailAddresses"] = parsedCertificate.EmailAddresses
logEvent.Extra["RetrievedCertificateIPAddresses"] = parsedCertificate.IPAddresses
certStatus, err := wfe.SA.GetCertificateStatus(serial)
if err != nil {
logEvent.AddError("unable to get certificate status: %s", err)
// TODO(#991): handle db errors
wfe.sendError(response, logEvent, probs.NotFound("Certificate status not yet available"), err)
return
}
logEvent.Extra["CertificateStatus"] = certStatus.Status
if certStatus.Status == core.OCSPStatusRevoked {
logEvent.AddError("Certificate already revoked: %#v", serial)
wfe.sendError(response, logEvent, probs.Conflict("Certificate already revoked"), nil)
return
}
// TODO: Implement method of revocation by authorizations on account.
if !(core.KeyDigestEquals(requestKey, parsedCertificate.PublicKey) ||
registration.ID == cert.RegistrationID) {
wfe.sendError(response, logEvent,
probs.Unauthorized("Revocation request must be signed by private key of cert to be revoked, or by the account key of the account that issued it."),
nil)
return
}
// Use revocation code 0, meaning "unspecified"
err = wfe.RA.RevokeCertificateWithReg(*parsedCertificate, 0, registration.ID)
if err != nil {
logEvent.AddError("failed to revoke certificate: %s", err)
wfe.sendError(response, logEvent, core.ProblemDetailsForError(err, "Failed to revoke certificate"), err)
} else {
wfe.log.Debug(fmt.Sprintf("Revoked %v", serial))
response.WriteHeader(http.StatusOK)
}
}
开发者ID:dash1291,项目名称:boulder,代码行数:81,代码来源:web-front-end.go
示例6: NewRegistration
// NewRegistration is used by clients to submit a new registration/account
func (wfe *WebFrontEndImpl) NewRegistration(logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
body, key, _, prob := wfe.verifyPOST(logEvent, request, false, core.ResourceNewReg)
if prob != nil {
// verifyPOST handles its own setting of logEvent.Errors
wfe.sendError(response, logEvent, prob, nil)
return
}
if existingReg, err := wfe.SA.GetRegistrationByKey(*key); err == nil {
response.Header().Set("Location", fmt.Sprintf("%s%d", wfe.RegBase, existingReg.ID))
// TODO(#595): check for missing registration err
wfe.sendError(response, logEvent, probs.Conflict("Registration key is already in use"), err)
return
}
var init core.Registration
err := json.Unmarshal(body, &init)
if err != nil {
wfe.sendError(response, logEvent, probs.Malformed("Error unmarshaling JSON"), err)
return
}
if len(init.Agreement) > 0 && init.Agreement != wfe.SubscriberAgreementURL {
msg := fmt.Sprintf("Provided agreement URL [%s] does not match current agreement URL [%s]", init.Agreement, wfe.SubscriberAgreementURL)
wfe.sendError(response, logEvent, probs.Malformed(msg), nil)
return
}
init.Key = *key
init.InitialIP = net.ParseIP(request.Header.Get("X-Real-IP"))
if init.InitialIP == nil {
host, _, err := net.SplitHostPort(request.RemoteAddr)
if err == nil {
init.InitialIP = net.ParseIP(host)
} else {
logEvent.AddError("Couldn't parse RemoteAddr: %s", request.RemoteAddr)
wfe.sendError(response, logEvent, probs.ServerInternal("couldn't parse the remote (that is, the client's) address"), nil)
return
}
}
reg, err := wfe.RA.NewRegistration(init)
if err != nil {
logEvent.AddError("unable to create new registration: %s", err)
wfe.sendError(response, logEvent, core.ProblemDetailsForError(err, "Error creating new registration"), err)
return
}
logEvent.Requester = reg.ID
logEvent.Contacts = reg.Contact
// Use an explicitly typed variable. Otherwise `go vet' incorrectly complains
// that reg.ID is a string being passed to %d.
regURL := fmt.Sprintf("%s%d", wfe.RegBase, reg.ID)
responseBody, err := json.Marshal(reg)
if err != nil {
// ServerInternal because we just created this registration, and it
// should be OK.
logEvent.AddError("unable to marshal registration: %s", err)
wfe.sendError(response, logEvent, probs.ServerInternal("Error marshaling registration"), err)
return
}
response.Header().Add("Location", regURL)
response.Header().Set("Content-Type", "application/json")
response.Header().Add("Link", link(wfe.NewAuthz, "next"))
if len(wfe.SubscriberAgreementURL) > 0 {
response.Header().Add("Link", link(wfe.SubscriberAgreementURL, "terms-of-service"))
}
response.WriteHeader(http.StatusCreated)
response.Write(responseBody)
}
开发者ID:dash1291,项目名称:boulder,代码行数:72,代码来源:web-front-end.go
示例7: verifyPOST
// verifyPOST reads and parses the request body, looks up the Registration
// corresponding to its JWK, verifies the JWS signature, checks that the
// resource field is present and correct in the JWS protected header, and
// returns the JWS payload bytes, the key used to verify, and the corresponding
// Registration (or error). If regCheck is false, verifyPOST will still try to
// look up a registration object, and will return it if found. However, if no
// registration object is found, verifyPOST will attempt to verify the JWS using
// the key in the JWS headers, and return the key plus a dummy registration if
// successful. If a caller passes regCheck = false, it should plan on validating
// the key itself. verifyPOST also appends its errors to requestEvent.Errors so
// code calling it does not need to if they immediately return a response to the
// user.
func (wfe *WebFrontEndImpl) verifyPOST(logEvent *requestEvent, request *http.Request, regCheck bool, resource core.AcmeResource) ([]byte, *jose.JsonWebKey, core.Registration, *probs.ProblemDetails) {
// TODO: We should return a pointer to a registration, which can be nil,
// rather the a registration value with a sentinel value.
// https://github.com/letsencrypt/boulder/issues/877
reg := core.Registration{ID: 0}
if _, ok := request.Header["Content-Length"]; !ok {
wfe.stats.Inc("WFE.HTTP.ClientErrors.LengthRequiredError", 1, 1.0)
logEvent.AddError("missing Content-Length header on POST")
return nil, nil, reg, probs.ContentLengthRequired()
}
// Read body
if request.Body == nil {
wfe.stats.Inc("WFE.Errors.NoPOSTBody", 1, 1.0)
logEvent.AddError("no body on POST")
return nil, nil, reg, probs.Malformed("No body on POST")
}
bodyBytes, err := ioutil.ReadAll(request.Body)
if err != nil {
wfe.stats.Inc("WFE.Errors.UnableToReadRequestBody", 1, 1.0)
logEvent.AddError("unable to read request body")
return nil, nil, reg, probs.ServerInternal("unable to read request body")
}
body := string(bodyBytes)
// Parse as JWS
parsedJws, err := jose.ParseSigned(body)
if err != nil {
wfe.stats.Inc("WFE.Errors.UnableToParseJWS", 1, 1.0)
logEvent.AddError("could not JSON parse body into JWS: %s", err)
return nil, nil, reg, probs.Malformed("Parse error reading JWS")
}
// 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.stats.Inc("WFE.Errors.TooManyJWSSignaturesInPOST", 1, 1.0)
logEvent.AddError("too many signatures in POST body: %d", len(parsedJws.Signatures))
return nil, nil, reg, probs.Malformed("Too many signatures in POST body")
}
if len(parsedJws.Signatures) == 0 {
wfe.stats.Inc("WFE.Errors.JWSNotSignedInPOST", 1, 1.0)
logEvent.AddError("no signatures in POST body")
return nil, nil, reg, probs.Malformed("POST JWS not signed")
}
submittedKey := parsedJws.Signatures[0].Header.JsonWebKey
if submittedKey == nil {
wfe.stats.Inc("WFE.Errors.NoJWKInJWSSignatureHeader", 1, 1.0)
logEvent.AddError("no JWK in JWS signature header in POST body")
return nil, nil, reg, probs.Malformed("No JWK in JWS header")
}
var key *jose.JsonWebKey
reg, err = wfe.SA.GetRegistrationByKey(*submittedKey)
// Special case: If no registration was found, but regCheck is false, use an
// empty registration and the submitted key. The caller is expected to do some
// validation on the returned key.
if _, ok := err.(core.NoSuchRegistrationError); ok && !regCheck {
// When looking up keys from the registrations DB, we can be confident they
// are "good". But when we are verifying against any submitted key, we want
// to check its quality before doing the verify.
if err = wfe.keyPolicy.GoodKey(submittedKey.Key); err != nil {
wfe.stats.Inc("WFE.Errors.JWKRejectedByGoodKey", 1, 1.0)
logEvent.AddError("JWK in request was rejected by GoodKey: %s", err)
return nil, nil, reg, probs.Malformed(err.Error())
}
key = submittedKey
} else if err != nil {
// For all other errors, or if regCheck is true, return error immediately.
wfe.stats.Inc("WFE.Errors.UnableToGetRegistrationByKey", 1, 1.0)
logEvent.AddError("unable to fetch registration by the given JWK: %s", err)
if _, ok := err.(core.NoSuchRegistrationError); ok {
return nil, nil, reg, probs.Unauthorized(unknownKey)
}
return nil, nil, reg, core.ProblemDetailsForError(err, "")
} else {
// If the lookup was successful, use that key.
key = ®.Key
logEvent.Requester = reg.ID
logEvent.Contacts = reg.Contact
//.........这里部分代码省略.........
开发者ID:dash1291,项目名称:boulder,代码行数:101,代码来源:web-front-end.go
示例8: NewCertificate
// NewCertificate is used by clients to request the issuance of a cert for an
// authorized identifier.
func (wfe *WebFrontEndImpl) NewCertificate(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {
body, _, reg, prob := wfe.verifyPOST(ctx, logEvent, request, true, core.ResourceNewCert)
addRequesterHeader(response, logEvent.Requester)
if prob != nil {
// verifyPOST handles its own setting of logEvent.Errors
wfe.sendError(response, logEvent, prob, nil)
return
}
// Any version of the agreement is acceptable here. Version match is enforced in
// wfe.Registration when agreeing the first time. Agreement updates happen
// by mailing subscribers and don't require a registration update.
if reg.Agreement == "" {
wfe.sendError(response, logEvent, probs.Unauthorized("Must agree to subscriber agreement before any further actions"), nil)
return
}
var rawCSR core.RawCertificateRequest
err := json.Unmarshal(body, &rawCSR)
if err != nil {
logEvent.AddError("unable to JSON unmarshal CertificateRequest: %s", err)
wfe.sendError(response, logEvent, probs.Malformed("Error unmarshaling certificate request"), err)
return
}
if wfe.CheckMalformedCSR {
// Assuming a properly formatted CSR there should be two four byte SEQUENCE
// declarations then a two byte integer declaration which defines the version
// of the CSR. If those two bytes (at offset 8 and 9) and equal to 2 and 0
// then the CSR was generated by a pre-1.0.2 version of OpenSSL with a client
// which didn't explicitly set the version causing the integer to be malformed
// and encoding/asn1 will refuse to parse it. If this is the case exit early
// with a more useful error message.
if len(rawCSR.CSR) >= 10 && rawCSR.CSR[8] == 2 && rawCSR.CSR[9] == 0 {
logEvent.AddError("Pre-1.0.2 OpenSSL malformed CSR")
wfe.sendError(
response,
logEvent,
probs.Malformed("CSR generated using a pre-1.0.2 OpenSSL with a client that doesn't properly specify the CSR version"),
nil,
)
return
}
}
certificateRequest := core.CertificateRequest{Bytes: rawCSR.CSR}
certificateRequest.CSR, err = x509.ParseCertificateRequest(rawCSR.CSR)
if err != nil {
logEvent.AddError("unable to parse certificate request: %s", err)
wfe.sendError(response, logEvent, probs.Malformed("Error parsing certificate request"), err)
return
}
wfe.logCsr(request, certificateRequest, reg)
// Check that the key in the CSR is good. This will also be checked in the CA
// component, but we want to discard CSRs with bad keys as early as possible
// because (a) it's an easy check and we can save unnecessary requests and
// bytes on the wire, and (b) the CA logs all rejections as audit events, but
// a bad key from the client is just a malformed request and doesn't need to
// be audited.
if err := wfe.keyPolicy.GoodKey(certificateRequest.CSR.PublicKey); err != nil {
logEvent.AddError("CSR public key failed GoodKey: %s", err)
wfe.sendError(response, logEvent, probs.Malformed("Invalid key in certificate request :: %s", err), err)
return
}
logEvent.Extra["CSRDNSNames"] = certificateRequest.CSR.DNSNames
logEvent.Extra["CSREmailAddresses"] = certificateRequest.CSR.EmailAddresses
logEvent.Extra["CSRIPAddresses"] = certificateRequest.CSR.IPAddresses
// Create new certificate and return
// TODO IMPORTANT: The RA trusts the WFE to provide the correct key. If the
// WFE is compromised, *and* the attacker knows the public key of an account
// authorized for target site, they could cause issuance for that site by
// lying to the RA. We should probably pass a copy of the whole request to the
// RA for secondary validation.
cert, err := wfe.RA.NewCertificate(ctx, certificateRequest, reg.ID)
if err != nil {
logEvent.AddError("unable to create new cert: %s", err)
wfe.sendError(response, logEvent, core.ProblemDetailsForError(err, "Error creating new cert"), err)
return
}
// Make a URL for this certificate.
// We use only the sequential part of the serial number, because it should
// uniquely identify the certificate, and this makes it easy for anybody to
// enumerate and mirror our certificates.
parsedCertificate, err := x509.ParseCertificate([]byte(cert.DER))
if err != nil {
logEvent.AddError("unable to parse certificate: %s", err)
wfe.sendError(response, logEvent, probs.Malformed("Unable to parse certificate"), err)
return
}
serial := parsedCertificate.SerialNumber
certURL := wfe.relativeEndpoint(request, certPath+core.SerialToString(serial))
relativeIssuerPath := wfe.relativeEndpoint(request, issuerPath)
// TODO Content negotiation
response.Header().Add("Location", certURL)
response.Header().Add("Link", link(relativeIssuerPath, "up"))
response.Header().Set("Content-Type", "application/pkix-cert")
//.........这里部分代码省略.........
开发者ID:MTRNord,项目名称:boulder-freifunk_support,代码行数:101,代码来源:wfe.go
注:本文中的github.com/letsencrypt/boulder/core.ProblemDetailsForError函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论