From 913fdc16fb48e58eba65dbd71409d8aa33450289 Mon Sep 17 00:00:00 2001 From: Gesa Stupperich Date: Thu, 10 Aug 2023 10:08:37 +0100 Subject: [PATCH 1/8] feat: implement has2be SignCertificate handler --- manager/handlers/has2be/sign_certificate.go | 40 +++++++++++++++++++ .../handlers/has2be/sign_certificate_test.go | 3 ++ manager/mqtt/router.go | 11 +++++ .../ocpp/has2be/sign_certificate_request.go | 17 ++++++++ .../ocpp/has2be/sign_certificate_response.go | 13 ++++++ 5 files changed, 84 insertions(+) create mode 100644 manager/handlers/has2be/sign_certificate.go create mode 100644 manager/handlers/has2be/sign_certificate_test.go create mode 100644 manager/ocpp/has2be/sign_certificate_request.go create mode 100644 manager/ocpp/has2be/sign_certificate_response.go diff --git a/manager/handlers/has2be/sign_certificate.go b/manager/handlers/has2be/sign_certificate.go new file mode 100644 index 0000000..14ff4db --- /dev/null +++ b/manager/handlers/has2be/sign_certificate.go @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: Apache-2.0 + +package has2be + +import ( + "context" + handlers201 "github.com/thoughtworks/maeve-csms/manager/handlers/ocpp201" + "github.com/thoughtworks/maeve-csms/manager/ocpp" + typesHasToBe "github.com/thoughtworks/maeve-csms/manager/ocpp/has2be" + types201 "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" +) + +type SignCertificateHandler struct { + Handler201 handlers201.SignCertificateHandler +} + +func (s SignCertificateHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (ocpp.Response, error) { + req := request.(*typesHasToBe.SignCertificateRequestJson) + + req201 := &types201.SignCertificateRequestJson{ + Csr: req.Csr, + } + + if req.TypeOfCertificate != nil { + req201 = &types201.SignCertificateRequestJson{ + Csr: req.Csr, + CertificateType: (*types201.CertificateSigningUseEnumType)(req.TypeOfCertificate), + } + } + + res, err := s.Handler201.HandleCall(ctx, chargeStationId, req201) + if err != nil { + return nil, err + } + res201 := res.(*types201.SignCertificateResponseJson) + + return &typesHasToBe.SignCertificateResponseJson{ + Status: typesHasToBe.GenericStatusEnumType(res201.Status), + }, nil +} diff --git a/manager/handlers/has2be/sign_certificate_test.go b/manager/handlers/has2be/sign_certificate_test.go new file mode 100644 index 0000000..e7982f0 --- /dev/null +++ b/manager/handlers/has2be/sign_certificate_test.go @@ -0,0 +1,3 @@ +// SPDX-License-Identifier: Apache-2.0 + +package has2be_test diff --git a/manager/mqtt/router.go b/manager/mqtt/router.go index 3878462..b580029 100644 --- a/manager/mqtt/router.go +++ b/manager/mqtt/router.go @@ -187,6 +187,17 @@ func NewV16Router(emitter Emitter, }, }, }, + "SignCertificate": { + NewRequest: func() ocpp.Request { return new(has2be.SignCertificateRequestJson) }, + RequestSchema: "has2be/SignCertificateRequestJson.json", + ResponseSchema: "has2be/SignCertificateRequestJson.json", + Handler: handlersHasToBe.SignCertificateHandler{ + Handler201: handlers201.SignCertificateHandler{ + ChargeStationCertificateProvider: chargeStationCertProvider, + CallMaker: dataTransferCallMaker, + }, + }, + }, }, }, }, diff --git a/manager/ocpp/has2be/sign_certificate_request.go b/manager/ocpp/has2be/sign_certificate_request.go new file mode 100644 index 0000000..371629e --- /dev/null +++ b/manager/ocpp/has2be/sign_certificate_request.go @@ -0,0 +1,17 @@ +package has2be + +type CertificateSigningUseEnumType string + +const CertificateSigningUseEnumTypeChargingStationCertificate CertificateSigningUseEnumType = "ChargingStationCertificate" +const CertificateSigningUseEnumTypeV2GCertificate CertificateSigningUseEnumType = "V2GCertificate" + +type SignCertificateRequestJson struct { + // The Charging Station SHALL send the public key in form of a Certificate Signing + // Request (CSR) as described in the X.509 standard. + Csr string `json:"csr" yaml:"csr" mapstructure:"csr"` + + // TypeOfCertificate corresponds to the JSON schema field "typeOfCertificate". + TypeOfCertificate *CertificateSigningUseEnumType `json:"typeOfCertificate,omitempty" yaml:"typeOfCertificate,omitempty" mapstructure:"typeOfCertificate,omitempty"` +} + +func (*SignCertificateRequestJson) IsRequest() {} diff --git a/manager/ocpp/has2be/sign_certificate_response.go b/manager/ocpp/has2be/sign_certificate_response.go new file mode 100644 index 0000000..97afad9 --- /dev/null +++ b/manager/ocpp/has2be/sign_certificate_response.go @@ -0,0 +1,13 @@ +package has2be + +type GenericStatusEnumType string + +const GenericStatusEnumTypeAccepted GenericStatusEnumType = "Accepted" +const GenericStatusEnumTypeRejected GenericStatusEnumType = "Rejected" + +type SignCertificateResponseJson struct { + // Status corresponds to the JSON schema field "status". + Status GenericStatusEnumType `json:"status" yaml:"status" mapstructure:"status"` +} + +func (*SignCertificateResponseJson) IsResponse() {} From 756cc2ac259de5a82bbcb11fc02ca60bebc36da2 Mon Sep 17 00:00:00 2001 From: Gesa Stupperich Date: Thu, 10 Aug 2023 15:52:31 +0100 Subject: [PATCH 2/8] feat: implement has2be CertificateSigned handler --- .../has2be/certificate_signed_result.go | 21 +++++++++++++++++++ manager/mqtt/router.go | 9 ++++++++ .../ocpp/has2be/certificate_signed_request.go | 13 ++++++++++++ .../has2be/certificate_signed_response.go | 13 ++++++++++++ .../ocpp/has2be/sign_certificate_request.go | 5 ----- manager/ocpp/has2be/types.go | 5 +++++ 6 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 manager/handlers/has2be/certificate_signed_result.go create mode 100644 manager/ocpp/has2be/certificate_signed_request.go create mode 100644 manager/ocpp/has2be/certificate_signed_response.go diff --git a/manager/handlers/has2be/certificate_signed_result.go b/manager/handlers/has2be/certificate_signed_result.go new file mode 100644 index 0000000..ba56b49 --- /dev/null +++ b/manager/handlers/has2be/certificate_signed_result.go @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 + +package has2be + +import ( + "context" + + "github.com/thoughtworks/maeve-csms/manager/ocpp" + "github.com/thoughtworks/maeve-csms/manager/ocpp/has2be" + "golang.org/x/exp/slog" +) + +type CertificateSignedResultHandler struct{} + +func (c CertificateSignedResultHandler) HandleCallResult(ctx context.Context, chargeStationId string, request ocpp.Request, response ocpp.Response, state any) error { + resp := response.(*has2be.CertificateSignedResponseJson) + + slog.Info("certificate signed response", slog.Any("status", resp.Status)) + + return nil +} diff --git a/manager/mqtt/router.go b/manager/mqtt/router.go index b580029..b957724 100644 --- a/manager/mqtt/router.go +++ b/manager/mqtt/router.go @@ -221,6 +221,15 @@ func NewV16Router(emitter Emitter, Handler: handlers201.CertificateSignedResultHandler{}, }, }, + "iso15118": { // has2be extensions + "CertificateSigned": { + NewRequest: func() ocpp.Request { return new(has2be.CertificateSignedRequestJson) }, + NewResponse: func() ocpp.Response { return new(has2be.CertificateSignedResponseJson) }, + RequestSchema: "has2be/CertificateSignedRequest.json", + ResponseSchema: "has2be/CertificateSignedResponse.json", + Handler: handlersHasToBe.CertificateSignedResultHandler{}, + }, + }, }, }, }, diff --git a/manager/ocpp/has2be/certificate_signed_request.go b/manager/ocpp/has2be/certificate_signed_request.go new file mode 100644 index 0000000..c560de7 --- /dev/null +++ b/manager/ocpp/has2be/certificate_signed_request.go @@ -0,0 +1,13 @@ +package has2be + +type CertificateSignedRequestJson struct { + // The signed X.509 certificate, first DER encoded into binary, and then hex + // encoded into a case insensitive string. This can also contain the necessary sub + // CA certificates. In that case, the order should follow the certificate chain, + // starting from the leaf certificate. + + // TypeOfCertificate corresponds to the JSON schema field "typeOfCertificate". + TypeOfCertificate CertificateSigningUseEnumType `json:"typeOfCertificate" yaml:"typeOfCertificate" mapstructure:"typeOfCertificate"` +} + +func (*CertificateSignedRequestJson) IsRequest() {} diff --git a/manager/ocpp/has2be/certificate_signed_response.go b/manager/ocpp/has2be/certificate_signed_response.go new file mode 100644 index 0000000..41faa8d --- /dev/null +++ b/manager/ocpp/has2be/certificate_signed_response.go @@ -0,0 +1,13 @@ +package has2be + +type CertificateSignedStatusEnumType string + +type CertificateSignedResponseJson struct { + // Status corresponds to the JSON schema field "status". + Status CertificateSignedStatusEnumType `json:"status" yaml:"status" mapstructure:"status"` +} + +const CertificateSignedStatusEnumTypeAccepted CertificateSignedStatusEnumType = "Accepted" +const CertificateSignedStatusEnumTypeRejected CertificateSignedStatusEnumType = "Rejected" + +func (*CertificateSignedResponseJson) IsResponse() {} diff --git a/manager/ocpp/has2be/sign_certificate_request.go b/manager/ocpp/has2be/sign_certificate_request.go index 371629e..293fbfa 100644 --- a/manager/ocpp/has2be/sign_certificate_request.go +++ b/manager/ocpp/has2be/sign_certificate_request.go @@ -1,10 +1,5 @@ package has2be -type CertificateSigningUseEnumType string - -const CertificateSigningUseEnumTypeChargingStationCertificate CertificateSigningUseEnumType = "ChargingStationCertificate" -const CertificateSigningUseEnumTypeV2GCertificate CertificateSigningUseEnumType = "V2GCertificate" - type SignCertificateRequestJson struct { // The Charging Station SHALL send the public key in form of a Certificate Signing // Request (CSR) as described in the X.509 standard. diff --git a/manager/ocpp/has2be/types.go b/manager/ocpp/has2be/types.go index 3af19e2..997b5dc 100644 --- a/manager/ocpp/has2be/types.go +++ b/manager/ocpp/has2be/types.go @@ -6,6 +6,11 @@ const HashAlgorithmEnumTypeSHA256 HashAlgorithmEnumType = "SHA256" const HashAlgorithmEnumTypeSHA384 HashAlgorithmEnumType = "SHA384" const HashAlgorithmEnumTypeSHA512 HashAlgorithmEnumType = "SHA512" +type CertificateSigningUseEnumType string + +const CertificateSigningUseEnumTypeChargingStationCertificate CertificateSigningUseEnumType = "ChargingStationCertificate" +const CertificateSigningUseEnumTypeV2GCertificate CertificateSigningUseEnumType = "V2GCertificate" + type OCSPRequestDataType struct { // HashAlgorithm corresponds to the JSON schema field "hashAlgorithm". HashAlgorithm HashAlgorithmEnumType `json:"hashAlgorithm" yaml:"hashAlgorithm" mapstructure:"hashAlgorithm"` From e706d0a00389730357564e8ad25edbc22155df37 Mon Sep 17 00:00:00 2001 From: Gesa Stupperich Date: Mon, 14 Aug 2023 20:52:08 +0100 Subject: [PATCH 3/8] fix: add SPDX-License-Identifier --- manager/ocpp/has2be/authorize_request.go | 2 ++ manager/ocpp/has2be/authorize_response.go | 2 ++ manager/ocpp/has2be/certificate_signed_request.go | 2 ++ manager/ocpp/has2be/certificate_signed_response.go | 2 ++ manager/ocpp/has2be/get_15118_ev_certificate_request.go | 2 ++ manager/ocpp/has2be/get_15118_ev_certificate_response.go | 2 ++ manager/ocpp/has2be/get_certificate_status_request.go | 2 ++ manager/ocpp/has2be/get_certificate_status_response.go | 2 ++ manager/ocpp/has2be/sign_certificate_request.go | 2 ++ manager/ocpp/has2be/sign_certificate_response.go | 2 ++ manager/ocpp/has2be/types.go | 2 ++ 11 files changed, 22 insertions(+) diff --git a/manager/ocpp/has2be/authorize_request.go b/manager/ocpp/has2be/authorize_request.go index ea36e3e..7674a43 100644 --- a/manager/ocpp/has2be/authorize_request.go +++ b/manager/ocpp/has2be/authorize_request.go @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 + package has2be type IdTokenEnumType string diff --git a/manager/ocpp/has2be/authorize_response.go b/manager/ocpp/has2be/authorize_response.go index be72e5a..f5882de 100644 --- a/manager/ocpp/has2be/authorize_response.go +++ b/manager/ocpp/has2be/authorize_response.go @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 + package has2be type AuthorizationStatusEnumType string diff --git a/manager/ocpp/has2be/certificate_signed_request.go b/manager/ocpp/has2be/certificate_signed_request.go index c560de7..c965f91 100644 --- a/manager/ocpp/has2be/certificate_signed_request.go +++ b/manager/ocpp/has2be/certificate_signed_request.go @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 + package has2be type CertificateSignedRequestJson struct { diff --git a/manager/ocpp/has2be/certificate_signed_response.go b/manager/ocpp/has2be/certificate_signed_response.go index 41faa8d..cceb3eb 100644 --- a/manager/ocpp/has2be/certificate_signed_response.go +++ b/manager/ocpp/has2be/certificate_signed_response.go @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 + package has2be type CertificateSignedStatusEnumType string diff --git a/manager/ocpp/has2be/get_15118_ev_certificate_request.go b/manager/ocpp/has2be/get_15118_ev_certificate_request.go index b8c1d0c..f4692c4 100644 --- a/manager/ocpp/has2be/get_15118_ev_certificate_request.go +++ b/manager/ocpp/has2be/get_15118_ev_certificate_request.go @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 + package has2be type Get15118EVCertificateRequestJson struct { diff --git a/manager/ocpp/has2be/get_15118_ev_certificate_response.go b/manager/ocpp/has2be/get_15118_ev_certificate_response.go index a8c92bc..46dfc37 100644 --- a/manager/ocpp/has2be/get_15118_ev_certificate_response.go +++ b/manager/ocpp/has2be/get_15118_ev_certificate_response.go @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 + package has2be type Iso15118EVCertificateStatusEnumType string diff --git a/manager/ocpp/has2be/get_certificate_status_request.go b/manager/ocpp/has2be/get_certificate_status_request.go index 39dcd27..e7ad325 100644 --- a/manager/ocpp/has2be/get_certificate_status_request.go +++ b/manager/ocpp/has2be/get_certificate_status_request.go @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 + package has2be type GetCertificateStatusRequestJson struct { diff --git a/manager/ocpp/has2be/get_certificate_status_response.go b/manager/ocpp/has2be/get_certificate_status_response.go index 8e1708a..b2a601f 100644 --- a/manager/ocpp/has2be/get_certificate_status_response.go +++ b/manager/ocpp/has2be/get_certificate_status_response.go @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 + package has2be type GetCertificateStatusEnumType string diff --git a/manager/ocpp/has2be/sign_certificate_request.go b/manager/ocpp/has2be/sign_certificate_request.go index 293fbfa..f1e41d3 100644 --- a/manager/ocpp/has2be/sign_certificate_request.go +++ b/manager/ocpp/has2be/sign_certificate_request.go @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 + package has2be type SignCertificateRequestJson struct { diff --git a/manager/ocpp/has2be/sign_certificate_response.go b/manager/ocpp/has2be/sign_certificate_response.go index 97afad9..c1282b8 100644 --- a/manager/ocpp/has2be/sign_certificate_response.go +++ b/manager/ocpp/has2be/sign_certificate_response.go @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 + package has2be type GenericStatusEnumType string diff --git a/manager/ocpp/has2be/types.go b/manager/ocpp/has2be/types.go index 997b5dc..815b46a 100644 --- a/manager/ocpp/has2be/types.go +++ b/manager/ocpp/has2be/types.go @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 + package has2be type HashAlgorithmEnumType string From ea7dfcc8428edf059e136d234c5b04dc9ae28dc6 Mon Sep 17 00:00:00 2001 From: Gesa Stupperich Date: Mon, 14 Aug 2023 21:01:02 +0100 Subject: [PATCH 4/8] fix: instrument CertificateSigned handler with Open Telemetry instead of slog --- manager/handlers/has2be/certificate_signed_result.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/manager/handlers/has2be/certificate_signed_result.go b/manager/handlers/has2be/certificate_signed_result.go index ba56b49..cef7a27 100644 --- a/manager/handlers/has2be/certificate_signed_result.go +++ b/manager/handlers/has2be/certificate_signed_result.go @@ -4,18 +4,21 @@ package has2be import ( "context" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" "github.com/thoughtworks/maeve-csms/manager/ocpp" "github.com/thoughtworks/maeve-csms/manager/ocpp/has2be" - "golang.org/x/exp/slog" ) type CertificateSignedResultHandler struct{} func (c CertificateSignedResultHandler) HandleCallResult(ctx context.Context, chargeStationId string, request ocpp.Request, response ocpp.Response, state any) error { + span := trace.SpanFromContext(ctx) + resp := response.(*has2be.CertificateSignedResponseJson) - slog.Info("certificate signed response", slog.Any("status", resp.Status)) + span.SetAttributes(attribute.String("response.status", string(resp.Status))) return nil } From 188b2b02d7bb85e8783c7bda2c3c7405a4abf909 Mon Sep 17 00:00:00 2001 From: Gesa Stupperich Date: Tue, 15 Aug 2023 08:26:51 +0100 Subject: [PATCH 5/8] fix: decode Csr before passing it on if it's base64-encoded --- manager/handlers/has2be/sign_certificate.go | 32 +++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/manager/handlers/has2be/sign_certificate.go b/manager/handlers/has2be/sign_certificate.go index 14ff4db..73e91db 100644 --- a/manager/handlers/has2be/sign_certificate.go +++ b/manager/handlers/has2be/sign_certificate.go @@ -4,10 +4,14 @@ package has2be import ( "context" + "encoding/base64" + "encoding/pem" handlers201 "github.com/thoughtworks/maeve-csms/manager/handlers/ocpp201" "github.com/thoughtworks/maeve-csms/manager/ocpp" typesHasToBe "github.com/thoughtworks/maeve-csms/manager/ocpp/has2be" types201 "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) type SignCertificateHandler struct { @@ -15,15 +19,23 @@ type SignCertificateHandler struct { } func (s SignCertificateHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (ocpp.Response, error) { + span := trace.SpanFromContext(ctx) + req := request.(*typesHasToBe.SignCertificateRequestJson) + csr, inputFormat, err := normalizeCsrEncoding(req.Csr) + if err != nil { + return nil, err + } + span.SetAttributes(attribute.String("sign_certificate.input_format", inputFormat)) + req201 := &types201.SignCertificateRequestJson{ - Csr: req.Csr, + Csr: csr, } if req.TypeOfCertificate != nil { req201 = &types201.SignCertificateRequestJson{ - Csr: req.Csr, + Csr: csr, CertificateType: (*types201.CertificateSigningUseEnumType)(req.TypeOfCertificate), } } @@ -38,3 +50,19 @@ func (s SignCertificateHandler) HandleCall(ctx context.Context, chargeStationId Status: typesHasToBe.GenericStatusEnumType(res201.Status), }, nil } + +func normalizeCsrEncoding(csr string) (string, string, error) { + if pemDecoded, _ := pem.Decode([]byte(csr)); pemDecoded == nil { + base64Decoded, err := base64.StdEncoding.DecodeString(csr) + if err != nil { + return "", "", err + } + pemBlock := pem.Block{ + Type: "CERTIFICATE REQUEST", + Bytes: base64Decoded, + } + csr = string(pem.EncodeToMemory(&pemBlock)) + return csr, "base64", nil + } + return csr, "pem", nil +} From e1198d4f21be2b8ddfdc91724368720b7e30ec27 Mon Sep 17 00:00:00 2001 From: Gesa Stupperich Date: Mon, 21 Aug 2023 08:34:35 +0100 Subject: [PATCH 6/8] fix: add a test for has2be SignCertificate --- manager/handlers/has2be/authorize.go | 4 +- .../has2be/get_15118_ev_certificate.go | 4 +- .../handlers/has2be/get_certificate_status.go | 4 +- manager/handlers/has2be/sign_certificate.go | 12 ++- .../handlers/has2be/sign_certificate_test.go | 81 +++++++++++++++++++ 5 files changed, 95 insertions(+), 10 deletions(-) diff --git a/manager/handlers/has2be/authorize.go b/manager/handlers/has2be/authorize.go index a96fcac..0dbf981 100644 --- a/manager/handlers/has2be/authorize.go +++ b/manager/handlers/has2be/authorize.go @@ -4,14 +4,14 @@ package has2be import ( "context" - handlers201 "github.com/thoughtworks/maeve-csms/manager/handlers/ocpp201" + "github.com/thoughtworks/maeve-csms/manager/handlers" "github.com/thoughtworks/maeve-csms/manager/ocpp" typesHasToBe "github.com/thoughtworks/maeve-csms/manager/ocpp/has2be" types201 "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" ) type AuthorizeHandler struct { - Handler201 handlers201.AuthorizeHandler + Handler201 handlers.CallHandler } func (a AuthorizeHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (ocpp.Response, error) { diff --git a/manager/handlers/has2be/get_15118_ev_certificate.go b/manager/handlers/has2be/get_15118_ev_certificate.go index 84d3dbf..0325887 100644 --- a/manager/handlers/has2be/get_15118_ev_certificate.go +++ b/manager/handlers/has2be/get_15118_ev_certificate.go @@ -4,14 +4,14 @@ package has2be import ( "context" - handlers201 "github.com/thoughtworks/maeve-csms/manager/handlers/ocpp201" + "github.com/thoughtworks/maeve-csms/manager/handlers" "github.com/thoughtworks/maeve-csms/manager/ocpp" typesHasToBe "github.com/thoughtworks/maeve-csms/manager/ocpp/has2be" types201 "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" ) type Get15118EvCertificateHandler struct { - Handler201 handlers201.Get15118EvCertificateHandler + Handler201 handlers.CallHandler } func (g Get15118EvCertificateHandler) HandleCall(ctx context.Context, _ string, request ocpp.Request) (ocpp.Response, error) { diff --git a/manager/handlers/has2be/get_certificate_status.go b/manager/handlers/has2be/get_certificate_status.go index 5c2bb0a..31a37fe 100644 --- a/manager/handlers/has2be/get_certificate_status.go +++ b/manager/handlers/has2be/get_certificate_status.go @@ -4,14 +4,14 @@ package has2be import ( "context" - handlers201 "github.com/thoughtworks/maeve-csms/manager/handlers/ocpp201" + "github.com/thoughtworks/maeve-csms/manager/handlers" "github.com/thoughtworks/maeve-csms/manager/ocpp" typesHasToBe "github.com/thoughtworks/maeve-csms/manager/ocpp/has2be" types201 "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" ) type GetCertificateStatusHandler struct { - Handler201 handlers201.GetCertificateStatusHandler + Handler201 handlers.CallHandler } func (g GetCertificateStatusHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (ocpp.Response, error) { diff --git a/manager/handlers/has2be/sign_certificate.go b/manager/handlers/has2be/sign_certificate.go index 73e91db..88b7ac9 100644 --- a/manager/handlers/has2be/sign_certificate.go +++ b/manager/handlers/has2be/sign_certificate.go @@ -6,7 +6,8 @@ import ( "context" "encoding/base64" "encoding/pem" - handlers201 "github.com/thoughtworks/maeve-csms/manager/handlers/ocpp201" + + "github.com/thoughtworks/maeve-csms/manager/handlers" "github.com/thoughtworks/maeve-csms/manager/ocpp" typesHasToBe "github.com/thoughtworks/maeve-csms/manager/ocpp/has2be" types201 "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" @@ -15,7 +16,7 @@ import ( ) type SignCertificateHandler struct { - Handler201 handlers201.SignCertificateHandler + Handler201 handlers.CallHandler } func (s SignCertificateHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (ocpp.Response, error) { @@ -24,6 +25,7 @@ func (s SignCertificateHandler) HandleCall(ctx context.Context, chargeStationId req := request.(*typesHasToBe.SignCertificateRequestJson) csr, inputFormat, err := normalizeCsrEncoding(req.Csr) + if err != nil { return nil, err } @@ -53,16 +55,18 @@ func (s SignCertificateHandler) HandleCall(ctx context.Context, chargeStationId func normalizeCsrEncoding(csr string) (string, string, error) { if pemDecoded, _ := pem.Decode([]byte(csr)); pemDecoded == nil { - base64Decoded, err := base64.StdEncoding.DecodeString(csr) + // not PEM encoded, assume base64-encoded DER + der, err := base64.StdEncoding.DecodeString(csr) if err != nil { return "", "", err } pemBlock := pem.Block{ Type: "CERTIFICATE REQUEST", - Bytes: base64Decoded, + Bytes: der, } csr = string(pem.EncodeToMemory(&pemBlock)) return csr, "base64", nil } + return csr, "pem", nil } diff --git a/manager/handlers/has2be/sign_certificate_test.go b/manager/handlers/has2be/sign_certificate_test.go index e7982f0..f56efb9 100644 --- a/manager/handlers/has2be/sign_certificate_test.go +++ b/manager/handlers/has2be/sign_certificate_test.go @@ -1,3 +1,84 @@ // SPDX-License-Identifier: Apache-2.0 package has2be_test + +import ( + "context" + "encoding/base64" + "encoding/pem" + "github.com/stretchr/testify/assert" + handlersHasToBe "github.com/thoughtworks/maeve-csms/manager/handlers/has2be" + "github.com/thoughtworks/maeve-csms/manager/ocpp" + typesHasToBe "github.com/thoughtworks/maeve-csms/manager/ocpp/has2be" + types201 "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" + "testing" +) + +type spy201SignCertificateHandler struct { + RecordedCsr *string +} + +func (d spy201SignCertificateHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (ocpp.Response, error) { + d.recordReceivedCsr(request.(*types201.SignCertificateRequestJson).Csr) + return &types201.SignCertificateResponseJson{ + Status: types201.GenericStatusEnumTypeAccepted, + }, nil +} + +func (d *spy201SignCertificateHandler) recordReceivedCsr(csr string) { + *d.RecordedCsr = csr +} + +var csrBytes = []byte("some-csr") +var pemEncodedCsr = string(pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE REQUEST", + Bytes: csrBytes, +})) + +func TestPassesPEMEncodedCsrOnAsIs(t *testing.T) { + // it would be preferable to mock the dependencies of the 201 handler instead of the handler itself + // however, the 201 handler calls its dependencies from a go routine, but the things I tried in making the test wait + // for the go routine to finish (like passing a waitgroup into the mocked dependencies and calling wg.Done from + // its methods) didn't work + csrRecorder := "" + spy201Handler := spy201SignCertificateHandler{ + RecordedCsr: &csrRecorder, + } + handler := handlersHasToBe.SignCertificateHandler{ + Handler201: spy201Handler, + } + req := &typesHasToBe.SignCertificateRequestJson{ + Csr: pemEncodedCsr, + } + + _, err := handler.HandleCall(context.Background(), "cs001", req) + if err != nil { + t.Errorf("unexpected error %v", err) + } + + want := pemEncodedCsr + got := *spy201Handler.RecordedCsr + assert.Equal(t, want, got) +} + +func TestDecodesBase64EncodedDERAndReencodesAsPEM(t *testing.T) { + csrRecorder := "" + spy201Handler := spy201SignCertificateHandler{ + RecordedCsr: &csrRecorder, + } + handler := handlersHasToBe.SignCertificateHandler{ + Handler201: spy201Handler, + } + req := &typesHasToBe.SignCertificateRequestJson{ + Csr: base64.StdEncoding.EncodeToString(csrBytes), + } + + _, err := handler.HandleCall(context.Background(), "cs001", req) + if err != nil { + t.Errorf("unexpected error %v", err) + } + + want := pemEncodedCsr + got := *spy201Handler.RecordedCsr + assert.Equal(t, want, got) +} From 6f62a62e95cab605d1d7701da1d28ec6f746b07a Mon Sep 17 00:00:00 2001 From: Gesa Stupperich Date: Mon, 28 Aug 2023 14:38:29 +0100 Subject: [PATCH 7/8] fix: add has2be.CertificateSignedRequest to callmaker actions --- manager/mqtt/router.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/manager/mqtt/router.go b/manager/mqtt/router.go index b957724..2db7980 100644 --- a/manager/mqtt/router.go +++ b/manager/mqtt/router.go @@ -49,6 +49,10 @@ func NewV16Router(emitter Emitter, VendorId: "org.openchargealliance.iso15118pnc", MessageId: "CertificateSigned", }, + reflect.TypeOf(&has2be.CertificateSignedRequestJson{}): { + VendorId: "iso15118", + MessageId: "CertificateSigned", + }, }, } From a63d43cc458f75a7acf66abdf06b7a4ceddde6b3 Mon Sep 17 00:00:00 2001 From: Gesa Stupperich Date: Mon, 28 Aug 2023 14:34:25 +0100 Subject: [PATCH 8/8] fix: add content-type header to OCSP request --- manager/go.mod | 18 ++++---- manager/go.sum | 44 ++++++++++--------- manager/services/certificate_validation.go | 10 +++-- .../certificate_validation_hubject_test.go | 1 + 4 files changed, 41 insertions(+), 32 deletions(-) diff --git a/manager/go.mod b/manager/go.mod index 8dcfe6b..c03336d 100644 --- a/manager/go.mod +++ b/manager/go.mod @@ -20,7 +20,7 @@ require ( github.com/spf13/cobra v1.7.0 github.com/stretchr/testify v1.8.4 github.com/subnova/slog-exporter v0.1.0 - github.com/testcontainers/testcontainers-go v0.21.0 + github.com/testcontainers/testcontainers-go v0.23.0 github.com/unrolled/secure v1.13.0 go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 go.opentelemetry.io/contrib/detectors/gcp v1.17.0 @@ -32,7 +32,7 @@ require ( golang.org/x/crypto v0.10.0 golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691 google.golang.org/api v0.126.0 - google.golang.org/grpc v1.55.0 + google.golang.org/grpc v1.57.0 k8s.io/utils v0.0.0-20230505201702-9f6742963106 ) @@ -41,9 +41,10 @@ require ( cloud.google.com/go/compute v1.19.3 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/longrunning v0.5.0 // indirect + dario.cat/mergo v1.0.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.13.1 // indirect - github.com/Microsoft/go-winio v0.5.2 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect github.com/ajg/form v1.5.1 // indirect github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -51,12 +52,12 @@ require ( github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect - github.com/containerd/containerd v1.6.19 // indirect + github.com/containerd/containerd v1.7.3 // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/docker/docker v23.0.5+incompatible // indirect + github.com/docker/docker v24.0.5+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect @@ -80,7 +81,6 @@ require ( github.com/googleapis/gax-go/v2 v2.11.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect - github.com/imdario/mergo v0.3.15 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/invopop/yaml v0.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -108,7 +108,7 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc2 // indirect + github.com/opencontainers/image-spec v1.1.0-rc4 // indirect github.com/opencontainers/runc v1.1.5 // indirect github.com/perimeterx/marshmallow v1.1.4 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -131,12 +131,14 @@ require ( go.opentelemetry.io/otel/metric v1.16.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect golang.org/x/arch v0.3.0 // indirect + golang.org/x/mod v0.11.0 // indirect golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.9.0 // indirect + golang.org/x/sys v0.11.0 // indirect golang.org/x/text v0.10.0 // indirect golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.9.2 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect diff --git a/manager/go.sum b/manager/go.sum index c1b4b91..5173f38 100644 --- a/manager/go.sum +++ b/manager/go.sum @@ -40,16 +40,19 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.13.1 h1:hR+NqMEDDSR8hLc5ZybuWtPfhmFVZwd6Ft7n25XnVjk= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.13.1/go.mod h1:Xx0VKh7GJ4si3rmElbh19Mejxz68ibWg/J30ZOMrqzU= -github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= -github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= -github.com/Microsoft/hcsshim v0.9.7 h1:mKNHW/Xvv1aFH87Jb6ERDzXTJTLPlmzfZ28VBFD/bfg= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/hcsshim v0.10.0-rc.8 h1:YSZVvlIIDD1UxQpJp0h+dnpLUw+TrY0cx8obKsp3bek= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= @@ -87,9 +90,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/containerd/containerd v1.6.19 h1:F0qgQPrG0P2JPgwpxWxYavrVeXAG0ezUIB9Z/4FTUAU= -github.com/containerd/containerd v1.6.19/go.mod h1:HZCDMn4v/Xl2579/MvtOC2M206i+JJ6VxFWU/NetrGY= -github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/containerd v1.7.3 h1:cKwYKkP1eTj54bP3wCdXXBymmKRQMrWjkLSWZZJDa8o= +github.com/containerd/containerd v1.7.3/go.mod h1:32FOM4/O0RkNg7AjQj3hDzN9cUGtu+HMvaKUNiqCZB8= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= @@ -98,6 +100,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -109,8 +112,8 @@ github.com/deepmap/oapi-codegen v1.13.0 h1:cnFHelhsRQbYvanCUAbRSn/ZpkUb1HPRlQcu8 github.com/deepmap/oapi-codegen v1.13.0/go.mod h1:Amy7tbubKY9qkZOXqymI3Z6xSbndmu+atMJheLdyg44= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v23.0.5+incompatible h1:DaxtlTJjFSnLOXVNUBU1+6kXGz2lpDoEAH6QoxaSg8k= -github.com/docker/docker v23.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY= +github.com/docker/docker v24.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -250,8 +253,6 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4Zs github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= -github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc= @@ -338,8 +339,8 @@ github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= -github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= +github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= +github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -380,7 +381,6 @@ github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKP github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= @@ -408,8 +408,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/subnova/slog-exporter v0.1.0 h1:5Ge+50z1wsEKnfGHPcQH9r4S+3mnEhnNn5W0p+fY9do= github.com/subnova/slog-exporter v0.1.0/go.mod h1:WQ3oicsqaGWuj6VjnflRfXRfDrx0NH4PJOxKvpQoJfM= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/testcontainers/testcontainers-go v0.21.0 h1:syePAxdeTzfkap+RrJaQZpJQ/s/fsUgn11xIvHrOE9U= -github.com/testcontainers/testcontainers-go v0.21.0/go.mod h1:c1ez3WVRHq7T/Aj+X3TIipFBwkBaNT5iNCY8+1b83Ng= +github.com/testcontainers/testcontainers-go v0.23.0 h1:ERYTSikX01QczBLPZpqsETTBO7lInqEP349phDOVJVs= +github.com/testcontainers/testcontainers-go v0.23.0/go.mod h1:3gzuZfb7T9qfcH2pHpV4RLlWrPjeWNQah6XlYQ32c4I= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= @@ -509,6 +509,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -617,8 +619,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -685,6 +687,8 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.9.2 h1:UXbndbirwCAx6TULftIfie/ygDNCwxEie+IiNP1IcNc= +golang.org/x/tools v0.9.2/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -772,8 +776,8 @@ google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= +google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -804,7 +808,7 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/manager/services/certificate_validation.go b/manager/services/certificate_validation.go index 21929d6..0d82bc2 100644 --- a/manager/services/certificate_validation.go +++ b/manager/services/certificate_validation.go @@ -11,13 +11,12 @@ import ( "encoding/hex" "errors" "fmt" - "io" - "math/big" - "net/http" - "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201" "golang.org/x/crypto/ocsp" "golang.org/x/exp/slog" + "io" + "math/big" + "net/http" ) // OCSPError is an error returned by the OCSP server in response to a check @@ -275,6 +274,9 @@ func (o *OnlineCertificateValidationService) attemptOCSPCheck(ctx context.Contex return nil, fmt.Errorf("new request: %w", err) } + req.Header.Add("Content-Type", "application/ocsp-request") + req.Header.Add("Accept", "application/ocsp-response") + resp, err := o.HttpClient.Do(req) if err != nil { return nil, fmt.Errorf("post %s: %w", ocspResponderUrl, err) diff --git a/manager/services/certificate_validation_hubject_test.go b/manager/services/certificate_validation_hubject_test.go index e9051f7..a8f797a 100644 --- a/manager/services/certificate_validation_hubject_test.go +++ b/manager/services/certificate_validation_hubject_test.go @@ -60,6 +60,7 @@ func TestCertificateValidationServiceWithHubjectCertificateHashes(t *testing.T) httpClient), BaseURL: "https://open.plugncharge-test.hubject.com", ISOVersion: services.ISO15118V2, + HttpClient: httpClient, } csr := createCertificateSigningRequest(t)