Exemplo n.º 1
0
// Certificate is used by clients to request a copy of their current certificate, or to
// request a reissuance of the certificate.
func (wfe *WebFrontEndImpl) Certificate(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {

	serial := request.URL.Path
	// Certificate paths consist of the CertBase path, plus exactly sixteen hex
	// digits.
	if !core.ValidSerial(serial) {
		logEvent.AddError("certificate serial provided was not valid: %s", serial)
		wfe.sendError(response, logEvent, probs.NotFound("Certificate not found"), nil)
		return
	}
	logEvent.Extra["RequestedSerial"] = serial

	cert, err := wfe.SA.GetCertificate(ctx, serial)
	// TODO(#991): handle db errors
	if err != nil {
		logEvent.AddError("unable to get certificate by serial id %#v: %s", serial, err)
		if strings.HasPrefix(err.Error(), "gorp: multiple rows returned") {
			wfe.sendError(response, logEvent, probs.Conflict("Multiple certificates with same short serial"), err)
		} else {
			wfe.sendError(response, logEvent, probs.NotFound("Certificate not found"), err)
		}
		return
	}

	// TODO Content negotiation
	response.Header().Set("Content-Type", "application/pkix-cert")
	response.Header().Add("Link", link(issuerPath, "up"))
	response.WriteHeader(http.StatusOK)
	if _, err = response.Write(cert.DER); err != nil {
		logEvent.AddError(err.Error())
		wfe.log.Warning(fmt.Sprintf("Could not write response: %s", err))
	}
	return
}
Exemplo n.º 2
0
// Certificate is used by clients to request a copy of their current certificate, or to
// request a reissuance of the certificate.
func (wfe *WebFrontEndImpl) Certificate(ctx context.Context, logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {

	path := request.URL.Path
	// Certificate paths consist of the CertBase path, plus exactly sixteen hex
	// digits.
	if !strings.HasPrefix(path, CertPath) {
		logEvent.AddError("this request path should not have gotten to Certificate: %#v is not a prefix of %#v", path, CertPath)
		wfe.sendError(response, logEvent, probs.NotFound("Certificate not found"), nil)
		addNoCacheHeader(response)
		return
	}
	serial := path[len(CertPath):]
	if !core.ValidSerial(serial) {
		logEvent.AddError("certificate serial provided was not valid: %s", serial)
		wfe.sendError(response, logEvent, probs.NotFound("Certificate not found"), nil)
		addNoCacheHeader(response)
		return
	}
	logEvent.Extra["RequestedSerial"] = serial

	cert, err := wfe.SA.GetCertificate(ctx, serial)
	// TODO(#991): handle db errors
	if err != nil {
		logEvent.AddError("unable to get certificate by serial id %#v: %s", serial, err)
		if strings.HasPrefix(err.Error(), "gorp: multiple rows returned") {
			wfe.sendError(response, logEvent, probs.Conflict("Multiple certificates with same short serial"), err)
		} else {
			addNoCacheHeader(response)
			wfe.sendError(response, logEvent, probs.NotFound("Certificate not found"), err)
		}
		return
	}
	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
	}
	if err = wfe.addIssuerCertificateURLs(response, parsedCertificate); err != nil {
		logEvent.AddError("unable to parse IssuingCertificateURL: %s", err)
		wfe.sendError(response, logEvent, probs.Malformed("unable to parse IssuingCertificateURL"), err)
		return
	}
	addCacheHeader(response, wfe.CertCacheDuration.Seconds())

	// TODO Content negotiation
	response.Header().Set("Content-Type", "application/pkix-cert")
	response.WriteHeader(http.StatusOK)
	if _, err = response.Write(cert.DER); err != nil {
		logEvent.AddError(err.Error())
		wfe.log.Warning(fmt.Sprintf("Could not write response: %s", err))
	}
	return
}
Exemplo n.º 3
0
// GetCertificateStatus takes a hexadecimal string representing the full 128-bit serial
// number of a certificate and returns data about that certificate's current
// validity.
func (ssa *SQLStorageAuthority) GetCertificateStatus(ctx context.Context, serial string) (core.CertificateStatus, error) {
	if !core.ValidSerial(serial) {
		err := fmt.Errorf("Invalid certificate serial %s", serial)
		return core.CertificateStatus{}, err
	}

	var status core.CertificateStatus
	if features.Enabled(features.CertStatusOptimizationsMigrated) {
		statusObj, err := ssa.dbMap.Get(certStatusModelv2{}, serial)
		if err != nil {
			return status, err
		}
		if statusObj == nil {
			return status, nil
		}
		statusModel := statusObj.(*certStatusModelv2)
		status = core.CertificateStatus{
			Serial:                statusModel.Serial,
			SubscriberApproved:    statusModel.SubscriberApproved,
			Status:                statusModel.Status,
			OCSPLastUpdated:       statusModel.OCSPLastUpdated,
			RevokedDate:           statusModel.RevokedDate,
			RevokedReason:         statusModel.RevokedReason,
			LastExpirationNagSent: statusModel.LastExpirationNagSent,
			OCSPResponse:          statusModel.OCSPResponse,
			NotAfter:              statusModel.NotAfter,
			IsExpired:             statusModel.IsExpired,
			LockCol:               statusModel.LockCol,
		}
	} else {
		statusObj, err := ssa.dbMap.Get(certStatusModelv1{}, serial)
		if err != nil {
			return status, err
		}
		if statusObj == nil {
			return status, nil
		}
		statusModel := statusObj.(*certStatusModelv1)
		status = core.CertificateStatus{
			Serial:                statusModel.Serial,
			SubscriberApproved:    statusModel.SubscriberApproved,
			Status:                statusModel.Status,
			OCSPLastUpdated:       statusModel.OCSPLastUpdated,
			RevokedDate:           statusModel.RevokedDate,
			RevokedReason:         statusModel.RevokedReason,
			LastExpirationNagSent: statusModel.LastExpirationNagSent,
			OCSPResponse:          statusModel.OCSPResponse,
			LockCol:               statusModel.LockCol,
		}
	}

	return status, nil
}
Exemplo n.º 4
0
// GetCertificateStatus takes a hexadecimal string representing the full 128-bit serial
// number of a certificate and returns data about that certificate's current
// validity.
func (ssa *SQLStorageAuthority) GetCertificateStatus(serial string) (status core.CertificateStatus, err error) {
	if !core.ValidSerial(serial) {
		err := fmt.Errorf("Invalid certificate serial %s", serial)
		return core.CertificateStatus{}, err
	}

	certificateStats, err := ssa.dbMap.Get(core.CertificateStatus{}, serial)
	if err != nil {
		return
	}
	status = *certificateStats.(*core.CertificateStatus)
	return
}
Exemplo n.º 5
0
// GetCertificate takes a serial number and returns the corresponding
// certificate, or error if it does not exist.
func (ssa *SQLStorageAuthority) GetCertificate(ctx context.Context, serial string) (core.Certificate, error) {
	if !core.ValidSerial(serial) {
		err := fmt.Errorf("Invalid certificate serial %s", serial)
		return core.Certificate{}, err
	}

	cert, err := SelectCertificate(ssa.dbMap, "WHERE serial = ?", serial)
	if err == sql.ErrNoRows {
		return core.Certificate{}, core.NotFoundError(fmt.Sprintf("No certificate found for %s", serial))
	}
	if err != nil {
		return core.Certificate{}, err
	}
	return cert, err
}
Exemplo n.º 6
0
// Certificate is used by clients to request a copy of their current certificate, or to
// request a reissuance of the certificate.
func (wfe *WebFrontEndImpl) Certificate(response http.ResponseWriter, request *http.Request) {
	logEvent := wfe.populateRequestEvent(request)
	defer wfe.logRequestDetails(&logEvent)

	path := request.URL.Path
	// Certificate paths consist of the CertBase path, plus exactly sixteen hex
	// digits.
	if !strings.HasPrefix(path, CertPath) {
		logEvent.Error = "Certificate not found"
		wfe.sendError(response, logEvent.Error, path, http.StatusNotFound)
		addNoCacheHeader(response)
		return
	}
	serial := path[len(CertPath):]
	if !core.ValidSerial(serial) {
		logEvent.Error = "Certificate not found"
		wfe.sendError(response, logEvent.Error, serial, http.StatusNotFound)
		addNoCacheHeader(response)
		return
	}
	wfe.log.Debug(fmt.Sprintf("Requested certificate ID %s", serial))
	logEvent.Extra["RequestedSerial"] = serial

	cert, err := wfe.SA.GetCertificate(serial)
	if err != nil {
		logEvent.Error = err.Error()
		if strings.HasPrefix(err.Error(), "gorp: multiple rows returned") {
			wfe.sendError(response, "Multiple certificates with same short serial", err, http.StatusConflict)
		} else {
			addNoCacheHeader(response)
			wfe.sendError(response, "Certificate not found", err, http.StatusNotFound)
		}
		return
	}

	addCacheHeader(response, wfe.CertCacheDuration.Seconds())

	// TODO Content negotiation
	response.Header().Set("Content-Type", "application/pkix-cert")
	response.Header().Add("Link", link(IssuerPath, "up"))
	response.WriteHeader(http.StatusOK)
	if _, err = response.Write(cert.DER); err != nil {
		logEvent.Error = err.Error()
		wfe.log.Warning(fmt.Sprintf("Could not write response: %s", err))
	}
	return
}
Exemplo n.º 7
0
// Certificate is used by clients to request a copy of their current certificate, or to
// request a reissuance of the certificate.
func (wfe *WebFrontEndImpl) Certificate(logEvent *requestEvent, response http.ResponseWriter, request *http.Request) {

	path := request.URL.Path
	// Certificate paths consist of the CertBase path, plus exactly sixteen hex
	// digits.
	if !strings.HasPrefix(path, CertPath) {
		logEvent.AddError("this request path should not have gotten to Certificate: %#v is not a prefix of %#v", path, CertPath)
		wfe.sendError(response, logEvent, "Certificate not found", path, http.StatusNotFound)
		addNoCacheHeader(response)
		return
	}
	serial := path[len(CertPath):]
	if !core.ValidSerial(serial) {
		logEvent.AddError("certificate serial provided was not valid: %s", serial)
		wfe.sendError(response, logEvent, "Certificate not found", serial, http.StatusNotFound)
		addNoCacheHeader(response)
		return
	}
	logEvent.Extra["RequestedSerial"] = serial

	cert, err := wfe.SA.GetCertificate(serial)
	if err != nil {
		logEvent.AddError("unable to get certificate by serial id %#v: %s", serial, err)
		if strings.HasPrefix(err.Error(), "gorp: multiple rows returned") {
			wfe.sendError(response, logEvent, "Multiple certificates with same short serial", err, http.StatusConflict)
		} else {
			addNoCacheHeader(response)
			wfe.sendError(response, logEvent, "Certificate not found", err, http.StatusNotFound)
		}
		return
	}

	addCacheHeader(response, wfe.CertCacheDuration.Seconds())

	// TODO Content negotiation
	response.Header().Set("Content-Type", "application/pkix-cert")
	response.Header().Add("Link", link(IssuerPath, "up"))
	response.WriteHeader(http.StatusOK)
	if _, err = response.Write(cert.DER); err != nil {
		logEvent.AddError(err.Error())
		wfe.log.Warning(fmt.Sprintf("Could not write response: %s", err))
	}
	return
}
Exemplo n.º 8
0
// GetCertificate takes a serial number and returns the corresponding
// certificate, or error if it does not exist.
func (ssa *SQLStorageAuthority) GetCertificate(serial string) (core.Certificate, error) {
	if !core.ValidSerial(serial) {
		err := fmt.Errorf("Invalid certificate serial %s", serial)
		return core.Certificate{}, err
	}

	certObj, err := ssa.dbMap.Get(core.Certificate{}, serial)
	if err != nil {
		return core.Certificate{}, err
	}
	if certObj == nil {
		ssa.log.Debug(fmt.Sprintf("Nil cert for %s", serial))
		return core.Certificate{}, fmt.Errorf("Certificate does not exist for %s", serial)
	}

	certPtr, ok := certObj.(*core.Certificate)
	if !ok {
		ssa.log.Debug("Failed to convert cert")
		return core.Certificate{}, fmt.Errorf("Error converting certificate response for %s", serial)
	}
	return *certPtr, err
}