Skip to content

Commit

Permalink
fix certificateType on CertificateSignedRequest & GetInstalledCertifi…
Browse files Browse the repository at this point in the history
…cateIds request-response (base on json schemas)
  • Loading branch information
dwibudut authored and lorenzodonini committed Jul 3, 2023
1 parent c34f6ad commit 694d985
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 41 deletions.
4 changes: 2 additions & 2 deletions ocpp2.0.1/csms.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,8 @@ func (cs *csms) GetDisplayMessages(clientId string, callback func(*display.GetDi
return cs.SendRequestAsync(clientId, request, genericCallback)
}

func (cs *csms) GetInstalledCertificateIds(clientId string, callback func(*iso15118.GetInstalledCertificateIdsResponse, error), typeOfCertificate types.CertificateUse, props ...func(*iso15118.GetInstalledCertificateIdsRequest)) error {
request := iso15118.NewGetInstalledCertificateIdsRequest(typeOfCertificate)
func (cs *csms) GetInstalledCertificateIds(clientId string, callback func(*iso15118.GetInstalledCertificateIdsResponse, error), props ...func(*iso15118.GetInstalledCertificateIdsRequest)) error {
request := iso15118.NewGetInstalledCertificateIdsRequest()
for _, fn := range props {
fn(request)
}
Expand Down
11 changes: 6 additions & 5 deletions ocpp2.0.1/iso15118/get_installed_certificate_ids.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ func isValidGetInstalledCertificateStatus(fl validator.FieldLevel) bool {

// The field definition of the GetInstalledCertificateIdsRequest PDU sent by the CSMS to the Charging Station.
type GetInstalledCertificateIdsRequest struct {
TypeOfCertificate types.CertificateUse `json:"typeOfCertificate" validate:"required,certificateUse"`
CertificateTypes []types.CertificateUse `json:"certificateType" validate:"omitempty,dive,certificateUse"`
}

// The field definition of the GetInstalledCertificateIds response payload sent by the Charging Station to the CSMS in response to a GetInstalledCertificateIdsRequest.
type GetInstalledCertificateIdsResponse struct {
Status GetInstalledCertificateStatus `json:"status" validate:"required,getInstalledCertificateStatus"`
CertificateHashData []types.CertificateHashData `json:"certificateHashData,omitempty" validate:"omitempty,dive"`
Status GetInstalledCertificateStatus `json:"status" validate:"required,getInstalledCertificateStatus"`
StatusInfo *types.StatusInfo `json:"statusInfo,omitempty" validate:"omitempty"`
CertificateHashDataChain []types.CertificateHashDataChain `json:"certificateHashDataChain,omitempty" validate:"omitempty,dive"`
}

// To facilitate the management of the Charging Station’s installed certificates, a method of retrieving the installed certificates is provided.
Expand Down Expand Up @@ -66,8 +67,8 @@ func (c GetInstalledCertificateIdsResponse) GetFeatureName() string {
}

// Creates a new GetInstalledCertificateIdsRequest, containing all required fields. There are no optional fields for this message.
func NewGetInstalledCertificateIdsRequest(typeOfCertificate types.CertificateUse) *GetInstalledCertificateIdsRequest {
return &GetInstalledCertificateIdsRequest{TypeOfCertificate: typeOfCertificate}
func NewGetInstalledCertificateIdsRequest() *GetInstalledCertificateIdsRequest {
return &GetInstalledCertificateIdsRequest{}
}

// Creates a new NewGetInstalledCertificateIdsResponse, containing all required fields. Additional optional fields may be set afterwards.
Expand Down
2 changes: 1 addition & 1 deletion ocpp2.0.1/security/certificate_signed.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func isValidCertificateSignedStatus(fl validator.FieldLevel) bool {
// The field definition of the CertificateSignedRequest PDU sent by the CSMS to the Charging Station.
type CertificateSignedRequest struct {
CertificateChain string `json:"certificateChain" validate:"required,max=10000"`
TypeOfCertificate types.CertificateSigningUse `json:"typeOfCertificate,omitempty" validate:"omitempty,certificateSigningUse"`
TypeOfCertificate types.CertificateSigningUse `json:"certificateType,omitempty" validate:"omitempty,certificateSigningUse"`
}

// The field definition of the CertificateSignedResponse payload sent by the Charging Station to the CSMS in response to a CertificateSignedRequest.
Expand Down
10 changes: 9 additions & 1 deletion ocpp2.0.1/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ type CertificateHashData struct {
SerialNumber string `json:"serialNumber" validate:"required,max=20"`
}

// CertificateHashDataChain
type CertificateHashDataChain struct {
CertificateType CertificateUse `json:"certificateType" validate:"required,certificateUse"`
CertificateHashData CertificateHashData `json:"certificateHashData" validate:"required"`
ChildCertificateHashData []CertificateHashData `json:"childCertificateHashData,omitempty" validate:"omitempty,dive"`
}

// Certificate15118EVStatus
type Certificate15118EVStatus string

Expand Down Expand Up @@ -202,13 +209,14 @@ const (
CSOSubCA1 CertificateUse = "CSOSubCA1"
CSOSubCA2 CertificateUse = "CSOSubCA2"
CSMSRootCertificate CertificateUse = "CSMSRootCertificate"
V2GCertificateChain CertificateUse = "V2GCertificateChain"
ManufacturerRootCertificate CertificateUse = "ManufacturerRootCertificate"
)

func isValidCertificateUse(fl validator.FieldLevel) bool {
use := CertificateUse(fl.Field().String())
switch use {
case V2GRootCertificate, MORootCertificate, CSOSubCA1, CSOSubCA2, CSMSRootCertificate, ManufacturerRootCertificate:
case V2GRootCertificate, MORootCertificate, CSOSubCA1, CSOSubCA2, CSMSRootCertificate, V2GCertificateChain, ManufacturerRootCertificate:
return true
default:
return false
Expand Down
2 changes: 1 addition & 1 deletion ocpp2.0.1/v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ type CSMS interface {
// Retrieves all messages currently configured on a charging station.
GetDisplayMessages(clientId string, callback func(*display.GetDisplayMessagesResponse, error), requestId int, props ...func(*display.GetDisplayMessagesRequest)) error
// Retrieves all installed certificates on a charging station.
GetInstalledCertificateIds(clientId string, callback func(*iso15118.GetInstalledCertificateIdsResponse, error), typeOfCertificate types.CertificateUse, props ...func(*iso15118.GetInstalledCertificateIdsRequest)) error
GetInstalledCertificateIds(clientId string, callback func(*iso15118.GetInstalledCertificateIdsResponse, error), props ...func(*iso15118.GetInstalledCertificateIdsRequest)) error
// Queries a charging station for version number of the Local Authorization List.
GetLocalListVersion(clientId string, callback func(*localauth.GetLocalListVersionResponse, error), props ...func(*localauth.GetLocalListVersionRequest)) error
// Instructs a charging station to upload a diagnostics or security logfile to the CSMS.
Expand Down
4 changes: 2 additions & 2 deletions ocpp2.0.1_test/certificate_signed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (suite *OcppV2TestSuite) TestCertificateSignedE2EMocked() {
certificateChain := "someX509CertificateChain"
certificateType := types.ChargingStationCert
status := security.CertificateSignedStatusAccepted
requestJson := fmt.Sprintf(`[2,"%v","%v",{"certificateChain":"%v","typeOfCertificate":"%v"}]`,
requestJson := fmt.Sprintf(`[2,"%v","%v",{"certificateChain":"%v","certificateType":"%v"}]`,
messageId, security.CertificateSignedFeatureName, certificateChain, certificateType)
responseJson := fmt.Sprintf(`[3,"%v",{"status":"%v"}]`, messageId, status)
certificateSignedConfirmation := security.NewCertificateSignedResponse(status)
Expand Down Expand Up @@ -85,6 +85,6 @@ func (suite *OcppV2TestSuite) TestCertificateSignedInvalidEndpoint() {
certificateType := types.ChargingStationCert
certificateSignedRequest := security.NewCertificateSignedRequest(certificate)
certificateSignedRequest.TypeOfCertificate = certificateType
requestJson := fmt.Sprintf(`[2,"%v","%v",{"certificateChain":"%v","typeOfCertificate":"%v"}]`, messageId, security.CertificateSignedFeatureName, certificate, certificateType)
requestJson := fmt.Sprintf(`[2,"%v","%v",{"certificateChain":"%v","certificateType":"%v"}]`, messageId, security.CertificateSignedFeatureName, certificate, certificateType)
testUnsupportedRequestFromChargingStation(suite, certificateSignedRequest, requestJson, messageId)
}
61 changes: 32 additions & 29 deletions ocpp2.0.1_test/get_installed_certificate_ids_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,28 @@ import (
func (suite *OcppV2TestSuite) TestGetInstalledCertificateIdsRequestValidation() {
t := suite.T()
var testTable = []GenericTestEntry{
{iso15118.GetInstalledCertificateIdsRequest{TypeOfCertificate: types.V2GRootCertificate}, true},
{iso15118.GetInstalledCertificateIdsRequest{TypeOfCertificate: types.MORootCertificate}, true},
{iso15118.GetInstalledCertificateIdsRequest{TypeOfCertificate: types.CSOSubCA1}, true},
{iso15118.GetInstalledCertificateIdsRequest{TypeOfCertificate: types.CSOSubCA2}, true},
{iso15118.GetInstalledCertificateIdsRequest{TypeOfCertificate: types.CSMSRootCertificate}, true},
{iso15118.GetInstalledCertificateIdsRequest{TypeOfCertificate: types.ManufacturerRootCertificate}, true},
{iso15118.GetInstalledCertificateIdsRequest{}, false},
{iso15118.GetInstalledCertificateIdsRequest{TypeOfCertificate: "invalidCertificateUse"}, false},
{iso15118.GetInstalledCertificateIdsRequest{CertificateTypes: []types.CertificateUse{types.V2GRootCertificate}}, true},
{iso15118.GetInstalledCertificateIdsRequest{CertificateTypes: []types.CertificateUse{types.MORootCertificate}}, true},
{iso15118.GetInstalledCertificateIdsRequest{CertificateTypes: []types.CertificateUse{types.CSOSubCA1}}, true},
{iso15118.GetInstalledCertificateIdsRequest{CertificateTypes: []types.CertificateUse{types.CSOSubCA2}}, true},
{iso15118.GetInstalledCertificateIdsRequest{CertificateTypes: []types.CertificateUse{types.CSMSRootCertificate}}, true},
{iso15118.GetInstalledCertificateIdsRequest{CertificateTypes: []types.CertificateUse{types.ManufacturerRootCertificate}}, true},
{iso15118.GetInstalledCertificateIdsRequest{}, true},
{iso15118.GetInstalledCertificateIdsRequest{CertificateTypes: []types.CertificateUse{"invalidCertificateUse"}}, false},
}
ExecuteGenericTestTable(t, testTable)
}

func (suite *OcppV2TestSuite) TestGetInstalledCertificateIdsConfirmationValidation() {
t := suite.T()
var testTable = []GenericTestEntry{
{iso15118.GetInstalledCertificateIdsResponse{Status: iso15118.GetInstalledCertificateStatusAccepted, CertificateHashData: []types.CertificateHashData{{HashAlgorithm: types.SHA256, IssuerNameHash: "name0", IssuerKeyHash: "key0", SerialNumber: "serial0"}}}, true},
{iso15118.GetInstalledCertificateIdsResponse{Status: iso15118.GetInstalledCertificateStatusNotFound, CertificateHashData: []types.CertificateHashData{{HashAlgorithm: types.SHA256, IssuerNameHash: "name0", IssuerKeyHash: "key0", SerialNumber: "serial0"}}}, true},
{iso15118.GetInstalledCertificateIdsResponse{Status: iso15118.GetInstalledCertificateStatusAccepted, CertificateHashData: []types.CertificateHashData{}}, true},
{iso15118.GetInstalledCertificateIdsResponse{Status: iso15118.GetInstalledCertificateStatusAccepted, CertificateHashDataChain: []types.CertificateHashDataChain{{CertificateType: types.CSMSRootCertificate, CertificateHashData: types.CertificateHashData{HashAlgorithm: types.SHA256, IssuerNameHash: "name0", IssuerKeyHash: "key0", SerialNumber: "serial0"}}}}, true},
{iso15118.GetInstalledCertificateIdsResponse{Status: iso15118.GetInstalledCertificateStatusNotFound, CertificateHashDataChain: []types.CertificateHashDataChain{{CertificateType: types.CSMSRootCertificate, CertificateHashData: types.CertificateHashData{HashAlgorithm: types.SHA256, IssuerNameHash: "name0", IssuerKeyHash: "key0", SerialNumber: "serial0"}}}}, true},
{iso15118.GetInstalledCertificateIdsResponse{Status: iso15118.GetInstalledCertificateStatusAccepted, CertificateHashDataChain: []types.CertificateHashDataChain{}}, true},
{iso15118.GetInstalledCertificateIdsResponse{Status: iso15118.GetInstalledCertificateStatusAccepted}, true},
{iso15118.GetInstalledCertificateIdsResponse{}, false},
{iso15118.GetInstalledCertificateIdsResponse{Status: "invalidGetInstalledCertificateStatus"}, false},
{iso15118.GetInstalledCertificateIdsResponse{Status: iso15118.GetInstalledCertificateStatusAccepted, CertificateHashData: []types.CertificateHashData{{HashAlgorithm: "invalidHashAlgorithm", IssuerNameHash: "name0", IssuerKeyHash: "key0", SerialNumber: "serial0"}}}, false},
{iso15118.GetInstalledCertificateIdsResponse{Status: iso15118.GetInstalledCertificateStatusAccepted, CertificateHashDataChain: []types.CertificateHashDataChain{{CertificateType: types.CSMSRootCertificate, CertificateHashData: types.CertificateHashData{HashAlgorithm: "invalidHashAlgorithm", IssuerNameHash: "name0", IssuerKeyHash: "key0", SerialNumber: "serial0"}}}}, false},
}
ExecuteGenericTestTable(t, testTable)
}
Expand All @@ -46,24 +46,24 @@ func (suite *OcppV2TestSuite) TestGetInstalledCertificateIdsE2EMocked() {
wsId := "test_id"
messageId := defaultMessageId
wsUrl := "someUrl"
certificateType := types.CSMSRootCertificate
certificateTypes := []types.CertificateUse{types.CSMSRootCertificate}
status := iso15118.GetInstalledCertificateStatusAccepted
certificateHashData := []types.CertificateHashData{
{HashAlgorithm: types.SHA256, IssuerNameHash: "name0", IssuerKeyHash: "key0", SerialNumber: "serial0"},
certificateHashDataChain := []types.CertificateHashDataChain{
{CertificateType: types.CSMSRootCertificate, CertificateHashData: types.CertificateHashData{HashAlgorithm: types.SHA256, IssuerNameHash: "name0", IssuerKeyHash: "key0", SerialNumber: "serial0"}},
}
requestJson := fmt.Sprintf(`[2,"%v","%v",{"typeOfCertificate":"%v"}]`, messageId, iso15118.GetInstalledCertificateIdsFeatureName, certificateType)
responseJson := fmt.Sprintf(`[3,"%v",{"status":"%v","certificateHashData":[{"hashAlgorithm":"%v","issuerNameHash":"%v","issuerKeyHash":"%v","serialNumber":"%v"}]}]`,
messageId, status, certificateHashData[0].HashAlgorithm, certificateHashData[0].IssuerNameHash, certificateHashData[0].IssuerKeyHash, certificateHashData[0].SerialNumber)
requestJson := fmt.Sprintf(`[2,"%v","%v",{"certificateType":["%v"]}]`, messageId, iso15118.GetInstalledCertificateIdsFeatureName, certificateTypes[0])
responseJson := fmt.Sprintf(`[3,"%v",{"status":"%v","certificateHashDataChain":[{"certificateType":"%v","certificateHashData":{"hashAlgorithm":"%v","issuerNameHash":"%v","issuerKeyHash":"%v","serialNumber":"%v"}}]}]`,
messageId, status, certificateHashDataChain[0].CertificateType, certificateHashDataChain[0].CertificateHashData.HashAlgorithm, certificateHashDataChain[0].CertificateHashData.IssuerNameHash, certificateHashDataChain[0].CertificateHashData.IssuerKeyHash, certificateHashDataChain[0].CertificateHashData.SerialNumber)
getInstalledCertificateIdsConfirmation := iso15118.NewGetInstalledCertificateIdsResponse(status)
getInstalledCertificateIdsConfirmation.CertificateHashData = certificateHashData
getInstalledCertificateIdsConfirmation.CertificateHashDataChain = certificateHashDataChain
channel := NewMockWebSocket(wsId)
// Setting handlers
handler := &MockChargingStationIso15118Handler{}
handler.On("OnGetInstalledCertificateIds", mock.Anything).Return(getInstalledCertificateIdsConfirmation, nil).Run(func(args mock.Arguments) {
request, ok := args.Get(0).(*iso15118.GetInstalledCertificateIdsRequest)
require.True(t, ok)
require.NotNil(t, request)
assert.Equal(t, certificateType, request.TypeOfCertificate)
assert.Equal(t, certificateTypes, request.CertificateTypes)
})
setupDefaultCSMSHandlers(suite, expectedCSMSOptions{clientId: wsId, rawWrittenMessage: []byte(requestJson), forwardWrittenMessage: true})
setupDefaultChargingStationHandlers(suite, expectedChargingStationOptions{serverUrl: wsUrl, clientId: wsId, createChannelOnStart: true, channel: channel, rawWrittenMessage: []byte(responseJson), forwardWrittenMessage: true}, handler)
Expand All @@ -76,22 +76,25 @@ func (suite *OcppV2TestSuite) TestGetInstalledCertificateIdsE2EMocked() {
require.Nil(t, err)
require.NotNil(t, confirmation)
assert.Equal(t, status, confirmation.Status)
require.Len(t, confirmation.CertificateHashData, len(certificateHashData))
assert.Equal(t, certificateHashData[0].HashAlgorithm, confirmation.CertificateHashData[0].HashAlgorithm)
assert.Equal(t, certificateHashData[0].IssuerNameHash, confirmation.CertificateHashData[0].IssuerNameHash)
assert.Equal(t, certificateHashData[0].IssuerKeyHash, confirmation.CertificateHashData[0].IssuerKeyHash)
assert.Equal(t, certificateHashData[0].SerialNumber, confirmation.CertificateHashData[0].SerialNumber)
require.Len(t, confirmation.CertificateHashDataChain, len(certificateHashDataChain))
assert.Equal(t, certificateHashDataChain[0].CertificateHashData.HashAlgorithm, confirmation.CertificateHashDataChain[0].CertificateHashData.HashAlgorithm)
assert.Equal(t, certificateHashDataChain[0].CertificateHashData.IssuerNameHash, confirmation.CertificateHashDataChain[0].CertificateHashData.IssuerNameHash)
assert.Equal(t, certificateHashDataChain[0].CertificateHashData.IssuerKeyHash, confirmation.CertificateHashDataChain[0].CertificateHashData.IssuerKeyHash)
assert.Equal(t, certificateHashDataChain[0].CertificateHashData.SerialNumber, confirmation.CertificateHashDataChain[0].CertificateHashData.SerialNumber)
resultChannel <- true
}, certificateType)
}, func(request *iso15118.GetInstalledCertificateIdsRequest) {
request.CertificateTypes = certificateTypes
})
require.Nil(t, err)
result := <-resultChannel
assert.True(t, result)
}

func (suite *OcppV2TestSuite) TestGetInstalledCertificateIdsInvalidEndpoint() {
messageId := defaultMessageId
certificateType := types.CSMSRootCertificate
GetInstalledCertificateIdsRequest := iso15118.NewGetInstalledCertificateIdsRequest(certificateType)
requestJson := fmt.Sprintf(`[2,"%v","%v",{"typeOfCertificate":"%v"}]`, messageId, iso15118.GetInstalledCertificateIdsFeatureName, certificateType)
certificateTypes := []types.CertificateUse{types.CSMSRootCertificate}
GetInstalledCertificateIdsRequest := iso15118.NewGetInstalledCertificateIdsRequest()
GetInstalledCertificateIdsRequest.CertificateTypes = certificateTypes
requestJson := fmt.Sprintf(`[2,"%v","%v",{"certificateType":["%v"]}]`, messageId, iso15118.GetInstalledCertificateIdsFeatureName, certificateTypes[0])
testUnsupportedRequestFromChargingStation(suite, GetInstalledCertificateIdsRequest, requestJson, messageId)
}

0 comments on commit 694d985

Please sign in to comment.