Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ITS - Intelligent Transport Systems
ITS
Commits
3824b1be
Commit
3824b1be
authored
Oct 24, 2016
by
garciay
Browse files
Bug fixed validating Security with Commsignia
parent
85e1745a
Changes
2
Hide whitespace changes
Inline
Side-by-side
ttcn/AtsDENM/ItsDenm_TpFunctions.ttcn
View file @
3824b1be
...
...
@@ -802,9 +802,12 @@ module ItsDenm_TpFunctions {
f_utTriggerEvent
(
m_utTriggerEvent
(
v_situation
));
f_awaitDenMessage
(
mw_denmInd
(
mw_anyDenmPdu
),
v_denmInd
);
v_timestampIts
:=
f_getCurrentTime
();
//log("v_timestampIts: ", v_timestampIts);
v_actionId
:=
v_denmInd
.
msgIn
.
denm
.
management
.
actionID
;
v_referenceTime1
:=
v_denmInd
.
msgIn
.
denm
.
management
.
referenceTime
;
//log("v_referenceTime1: ", v_referenceTime1);
v_diff
:=
v_timestampIts
-
v_referenceTime1
;
//log("v_diff: ", v_diff);
f_selfOrClientSyncAndVerdictPreamble
(
c_prDone
,
e_success
);
// Test Body
...
...
@@ -827,7 +830,9 @@ module ItsDenm_TpFunctions {
)
->
value
v_denmInd
{
tc_ac
.
stop
;
v_timestampIts
:=
f_getCurrentTime
();
//log("v_timestampIts: ", v_timestampIts);
v_msgtimestamp
:=
v_denmInd
.
msgIn
.
denm
.
management
.
referenceTime
;
//log("v_msgtimestamp: ", v_msgtimestamp);
if
(
(
(
v_timestampIts
+
v_diff
)
>
v_msgtimestamp
)
and
(
v_msgtimestamp
>
v_referenceTime1
)
)
{
log
(
"*** "
&
testcasename
()
&
": PASS: Successfully received expected DENM. ***"
);
f_selfOrClientSyncAndVerdict
(
c_tbDone
,
e_success
);
...
...
@@ -1535,8 +1540,7 @@ module ItsDenm_TpFunctions {
const
float
c_upperRepetitionInterval
:=
int2float
(
c_repetitionInterval
)
*
1.05
;
// Local variables
var
template
(
value
)
SituationContainer
v_situation
:=
m_situation
(
CauseCodeType_vehicleBreakdown_
,
VehicleBreakdownSubCauseCode_unavailable_
);
var
template
(
present
)
DenmInd
v_expectedDenmInd
:=
mw_denmInd
(
mw_denmPdu
(
mw_denm
(
mw_denmMgmtCon
(
mw_actionId
,
-
,
-
,
c_validityDuration
))));
var
template
(
present
)
DenmInd
v_expectedDenmInd
:=
mw_denmInd
(
mw_denmPdu
(
mw_denm
(
mw_denmMgmtCon
(
mw_actionId
,
-
,
-
,
c_validityDuration
))));
var
ActionID
v_actionId
;
var
DenmInd
v_denmInd
;
// Local timers
...
...
@@ -2924,7 +2928,7 @@ module ItsDenm_TpFunctions {
function
f_DEN_MSRV_BO_08_01
()
runs
on
ItsDenm
{
f_DEN_MSRV_BO_08_XX
(
"CERT_TS_DENM_
01
"
,
"CERT_TS_DENM_
BO_01_AT
"
,
m_situation
(
CauseCodeType_trafficCondition_
,
TrafficConditionSubCauseCode_unavailable_
)
);
}
...
...
@@ -2932,7 +2936,7 @@ module ItsDenm_TpFunctions {
function
f_DEN_MSRV_BO_08_02
()
runs
on
ItsDenm
{
f_DEN_MSRV_BO_08_XX
(
"CERT_TS_DENM_
02
"
,
"CERT_TS_DENM_
BO_02_AT
"
,
m_situation
(
CauseCodeType_accident_
,
AccidentSubCauseCode_unavailable_
)
);
}
...
...
@@ -2980,6 +2984,7 @@ module ItsDenm_TpFunctions {
);
f_sleep
(
1.0
);
vc_utEvents
:=
{};
// instruct adapter to use p_certName to sign message
if
(
e_success
!=
f_acTriggerSecEvent
(
m_acEnableSecurity
(
p_certName
)))
{
...
...
@@ -3025,7 +3030,7 @@ module ItsDenm_TpFunctions {
function
f_DEN_MSRV_BO_09_01
()
runs
on
ItsDenm
{
f_DEN_MSRV_BO_09_XX
(
"CERT_TS_DENM_
01
"
,
"CERT_TS_DENM_
BO_01_AT
"
,
m_situation
(
CauseCodeType_trafficCondition_
,
TrafficConditionSubCauseCode_unavailable_
),
m_situation
(
CauseCodeType_trafficCondition_
,
TrafficConditionSubCauseCode_trafficJamIncreasing_
)
);
...
...
@@ -3034,7 +3039,7 @@ module ItsDenm_TpFunctions {
function
f_DEN_MSRV_BO_09_02
()
runs
on
ItsDenm
{
f_DEN_MSRV_BO_09_XX
(
"CERT_TS_DENM_
02
"
,
"CERT_TS_DENM_
BO_02_AT
"
,
m_situation
(
CauseCodeType_accident_
,
AccidentSubCauseCode_unavailable_
),
m_situation
(
CauseCodeType_accident_
,
AccidentSubCauseCode_multiVehicleAccident_
)
);
...
...
ttcn/AtsSecurity/AtsSecurity_TestCases.ttcn3
View file @
3824b1be
...
...
@@ -1526,36 +1526,36 @@ module AtsSecurity_TestCases {
* Config Id: CF01
* Initial conditions:
* </pre>
* with
*
the IUT being in the 'authorized' state
*
and the IUT is configured to send more than one CAM per second
*
and the IUT having already sent a CAM
*
containing header_fields['signer_info'].signer.type
*
indicating 'certificate'
*
at TIME_1
*
and the IUT having received a SecuredMessage
*
containing header_fields['request_unrecognized_certificate']
*
containing digests
*
containing HashedId3 value (HASH1)
*
referencing to the AA certificate
*
at TIME_2 (TIME_1 < TIME_2 < TIME_1+1sec)
*
and the IUT having received a SecuredMessage
*
containing header_fields['signer_info'].signer.type
*
indicating 'certificate_chain'
*
containing AA certificate
*
having HashedId3 value of HASH1
*
at TIME_3 (TIME_2 < TIME_3 < TIME_2+0.1sec)
* ensure that
*
when
*
the IUT is requested to send a CAM
*
at TIME_3 (TIME_1 < TIME_2 < TIME_3 < TIME_1+1sec)
*
then
*
the IUT sends a SecuredMessage
*
and containing header_fields['signer_info']
*
containing signer
*
containing type
*
indicating 'digest'
*
or indicating 'certificate'
* with
*
the IUT being in the 'authorized' state
*
and the IUT is configured to send more than one CAM per second
*
and the IUT having already sent a CAM
*
containing header_fields['signer_info'].signer.type
*
indicating 'certificate'
*
at TIME_1
*
and the IUT having received a SecuredMessage
*
containing header_fields['request_unrecognized_certificate']
*
containing digests
*
containing HashedId3 value (HASH1)
*
referencing to the AA certificate
*
at TIME_2 (TIME_1 < TIME_2 < TIME_1+1sec)
*
and the IUT having received a SecuredMessage
*
containing header_fields['signer_info'].signer.type
*
indicating 'certificate_chain'
*
containing AA certificate
*
having HashedId3 value of HASH1
*
at TIME_3 (TIME_2 < TIME_3 < TIME_2+0.1sec)
* ensure that
*
when
*
the IUT is requested to send a CAM
*
at TIME_3 (TIME_1 < TIME_2 < TIME_3 < TIME_1+1sec)
*
then
*
the IUT sends a SecuredMessage
*
and containing header_fields['signer_info']
*
containing signer
*
containing type
*
indicating 'digest'
*
or indicating 'certificate'
*
* @see ETSI TS 103 096-2 v1.3.3 TP_SEC_ITSS_SND_CAM_09_02_BV
* @reference ETSI TS 103 097 [1], clause 7.1
...
...
@@ -1618,7 +1618,7 @@ module AtsSecurity_TestCases {
f_sendSecuredCam(
cc_taCert_A1,
omit,
e_certificate_chain
e_certificate_chain
);
f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
...
...
@@ -1641,18 +1641,18 @@ module AtsSecurity_TestCases {
log("*** " & testcasename() & ": FAIL: CAM retransmition with unexpected certificate_chain ***");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
}
[] geoNetworkingPort.receive(
mw_geoNwInd(
mw_geoNwSecPdu(
mdw_securedMessage_CAMs
))) {
log("*** " & testcasename() & ": INFO: CAM retransmission w/o certificate chain ***");
repeat;
}
[] geoNetworkingPort.receive(
mw_geoNwInd(
mw_geoNwSecPdu(
mdw_securedMessage_CAMs
))) {
log("*** " & testcasename() & ": INFO: CAM retransmission w/o certificate chain ***");
repeat;
}
[] t_maxTransInterval.timeout {
tc_ac.stop;
log("*** " & testcasename() & ": PASS: Generation of CAM messages including certificate chain was successfully skipped ***");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success);
log("*** " & testcasename() & ": PASS: Generation of CAM messages including certificate chain was successfully skipped ***");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success);
}
[] tc_ac.timeout {
...
...
@@ -1793,19 +1793,20 @@ module AtsSecurity_TestCases {
log("*** " & testcasename() & ": PASS: Generation time within certificate validity ***");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success);
} else if (f_getCertificateValidityRestriction(v_certificate, e_time_start_and_duration, v_validity) == true) {
if (PICS_PLUGTEST_VERSION) {
log("*** " & testcasename() & ": FAIL: Usage of time_start_and_duration is forbidden in TS103097 v1.2.5 ***");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
}
if ((v_generationTime >= (v_validity.validity.time_start_and_duration.start_validity * 1000000)) and
(v_generationTime < (f_duration2time(v_validity.validity.time_start_and_duration.duration_) * 1000000))
) {
log("*** " & testcasename() & ": PASS: Generation time within certificate validity ***");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success);
}
if (PICS_PLUGTEST_VERSION) {
log("*** " & testcasename() & ": FAIL: Usage of time_start_and_duration is forbidden in TS103097 v1.2.5 ***");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
}
if ((v_generationTime >= (v_validity.validity.time_start_and_duration.start_validity * 1000000)) and
(v_generationTime < (f_duration2time(v_validity.validity.time_start_and_duration.duration_) * 1000000))
) {
log("*** " & testcasename() & ": PASS: Generation time within certificate validity ***");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success);
}
} else {
log("*** " & testcasename() & ": FAIL: Generation time not within certificate validity ***");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
}
log("*** " & testcasename() & ": FAIL: Generation time not within certificate validity ***");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
}
[] geoNetworkingPort.receive(
mw_geoNwInd(
...
...
@@ -2008,100 +2009,100 @@ module AtsSecurity_TestCases {
f_poNeighbour();
f_cf01Down();
} // End of testcase TC_SEC_ITSS_SND_CAM_14_01_BV
/**
* @desc Check that the secured CAM contains only the trailer field of type signature
* and no other trailer fields
* <pre>
* Pics Selection: PICS_GN_SECURITY PICS_PLUGTEST_VERSION
* Config Id: CF01
* Initial conditions:
* with
*
the IUT being in the 'authorized' state
* ensure that
*
when
*
the IUT is requested to send a CAM
*
then
*
the IUT sends a SecuredMessage
*
containing trailer_fields
*
containing trailer_fields[0]
*
containing type
*
indicating 'signature'
*
and not containing any other items
/**
* @desc Check that the secured CAM contains only the trailer field of type signature
* and no other trailer fields
* <pre>
* Pics Selection: PICS_GN_SECURITY PICS_PLUGTEST_VERSION
* Config Id: CF01
* Initial conditions:
* with
*
the IUT being in the 'authorized' state
* ensure that
*
when
*
the IUT is requested to send a CAM
*
then
*
the IUT sends a SecuredMessage
*
containing trailer_fields
*
containing trailer_fields[0]
*
containing type
*
indicating 'signature'
*
and not containing any other items
* </pre>
*
* @see ETSI TS 103 096-2 v1.3.2 TP_SEC_ITSS_SND_CAM_15_01_BV
* @reference ETSI TS 103 097 [1], clause 7.1
*/
testcase TC_SEC_ITSS_SND_CAM_15_01_BV() runs on ItsGeoNetworking system ItsSecSystem {
// Local variables
const integer c_nbVerification := 3;
var integer v_nbVerification := 0;
var GeoNetworkingInd v_geoNwInd;
var SignerInfo v_signerInfo;
var Certificate v_certificate;
var boolean v_certificateReceived := false;
// Test control
if (not(PICS_GN_SECURITY)) {
log("*** " & testcasename() & ":ERROR: 'PICS_GN_SECURITY' required for executing the TC ***");
stop;
}
if (not(PICS_PLUGTEST_VERSION)) {
log("*** " & testcasename() & ":ERROR: 'PICS_PLUGTEST_VERSION' required for executing the TC ***");
stop;
}
// Test component configuration
f_cf01Up();
// Test adapter configuration
// Preamble
f_prNeighbour();
f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
// Test Body
tc_ac.start;
alt {
[] geoNetworkingPort.receive(
mw_geoNwInd(
mw_geoNwSecPdu(
mdw_securedMessage_CAMs(?, ?,
superset(mw_trailer_field_signature,
mw_trailer_field
))))){
tc_ac.stop;
log("*** " & testcasename() & ": FAIL: CAM received with more then one trailer fields");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
}
[] geoNetworkingPort.receive(
mw_geoNwInd(
mw_geoNwSecPdu(
mdw_securedMessage_CAMs(?, ?,
{ mw_trailer_field_signature }
)))){
tc_ac.stop;
log("*** " & testcasename() & ": INFO: CAM message with signature trailer received ***");
v_nbVerification := v_nbVerification + 1;
if (v_nbVerification < c_nbVerification) {
tc_ac.start;
repeat;
}
}
[] tc_ac.timeout {
log("*** " & testcasename() & ": INCONC: Expected CAM not received ***");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout);
}
} // End of 'alt' statement
log("*** " & testcasename() & ": PASS: All CAMs received with correct trailer fields count");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success);
// Postamble
f_poNeighbour();
f_cf01Down();
} // End of testcase TC_SEC_ITSS_SND_CAM_15_01_BV
* </pre>
*
* @see ETSI TS 103 096-2 v1.3.2 TP_SEC_ITSS_SND_CAM_15_01_BV
* @reference ETSI TS 103 097 [1], clause 7.1
*/
testcase TC_SEC_ITSS_SND_CAM_15_01_BV() runs on ItsGeoNetworking system ItsSecSystem {
// Local variables
const integer c_nbVerification := 3;
var integer v_nbVerification := 0;
var GeoNetworkingInd v_geoNwInd;
var SignerInfo v_signerInfo;
var Certificate v_certificate;
var boolean v_certificateReceived := false;
// Test control
if (not(PICS_GN_SECURITY)) {
log("*** " & testcasename() & ":ERROR: 'PICS_GN_SECURITY' required for executing the TC ***");
stop;
}
if (not(PICS_PLUGTEST_VERSION)) {
log("*** " & testcasename() & ":ERROR: 'PICS_PLUGTEST_VERSION' required for executing the TC ***");
stop;
}
// Test component configuration
f_cf01Up();
// Test adapter configuration
// Preamble
f_prNeighbour();
f_selfOrClientSyncAndVerdictPreamble(c_prDone, e_success);
// Test Body
tc_ac.start;
alt {
[] geoNetworkingPort.receive(
mw_geoNwInd(
mw_geoNwSecPdu(
mdw_securedMessage_CAMs(?, ?,
superset(mw_trailer_field_signature,
mw_trailer_field
))))){
tc_ac.stop;
log("*** " & testcasename() & ": FAIL: CAM received with more then one trailer fields");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
}
[] geoNetworkingPort.receive(
mw_geoNwInd(
mw_geoNwSecPdu(
mdw_securedMessage_CAMs(?, ?,
{ mw_trailer_field_signature }
)))){
tc_ac.stop;
log("*** " & testcasename() & ": INFO: CAM message with signature trailer received ***");
v_nbVerification := v_nbVerification + 1;
if (v_nbVerification < c_nbVerification) {
tc_ac.start;
repeat;
}
}
[] tc_ac.timeout {
log("*** " & testcasename() & ": INCONC: Expected CAM not received ***");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_timeout);
}
} // End of 'alt' statement
log("*** " & testcasename() & ": PASS: All CAMs received with correct trailer fields count");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_success);
// Postamble
f_poNeighbour();
f_cf01Down();
} // End of testcase TC_SEC_ITSS_SND_CAM_15_01_BV
/**
...
...
@@ -2682,10 +2683,10 @@ module AtsSecurity_TestCases {
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
}
} else if (v_cert.validity_restrictions[v_counter].type_ == e_time_start_and_duration) {
if (PICS_PLUGTEST_VERSION){
if (PICS_PLUGTEST_VERSION){
log("*** " & testcasename() & ": FAIL: Usage of time_start_and_duration is not allowed in TS103097 v1.2.5");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
}
}
v_startTime := v_cert.validity_restrictions[v_counter].validity.time_start_and_duration.start_validity * 1000000;
v_duration := f_duration2time(v_cert.validity_restrictions[v_counter].validity.time_start_and_duration.duration_) * 1000000;
if (not match(v_generationTime, Time64:(v_startTime .. v_duration))){
...
...
@@ -3263,25 +3264,25 @@ module AtsSecurity_TestCases {
* Config Id: CF01
* Initial conditions:
* with
*
the IUT being in the 'authorized' state
*
the IUT being in the 'authorized' state
* ensure that
*
when
*
the IUT is requested to send DENM
*
then
*
the IUT sends a SecuredMessage
*
containing trailer_fields
*
containing trailer_fields[0]
*
containing type
*
indicating 'signature'
*
and not containing other items
*
when
*
the IUT is requested to send DENM
*
then
*
the IUT sends a SecuredMessage
*
containing trailer_fields
*
containing trailer_fields[0]
*
containing type
*
indicating 'signature'
*
and not containing other items
* </pre>
* @see ETSI TS 103 096-2 v1.3.2 TP_SEC_ITSS_SND_DENM_09_01_BV
* @reference ETSI TS 103 097 [1], clause 7.2
*/
testcase TC_SEC_ITSS_SND_DENM_09_01_BV() runs on ItsGeoNetworking system ItsSecSystem {
// Local variables
const integer c_nbVerification := 3;
var integer v_nbVerification := 0;
const integer c_nbVerification := 3;
var integer v_nbVerification := 0;
var ItsDenm v_denmComponent;
// Test control
...
...
@@ -3290,10 +3291,10 @@ module AtsSecurity_TestCases {
stop;
}
if (not(PICS_PLUGTEST_VERSION)) {
log("*** " & testcasename() & ":ERROR: 'PICS_PLUGTEST_VERSION' required for executing the TC ***");
stop;
}
if (not(PICS_PLUGTEST_VERSION)) {
log("*** " & testcasename() & ":ERROR: 'PICS_PLUGTEST_VERSION' required for executing the TC ***");
stop;
}
// Test component configuration
f_cf01Up();
...
...
@@ -3306,26 +3307,26 @@ module AtsSecurity_TestCases {
// Test Body
tc_ac.start;
alt {
[] geoNetworkingPort.receive(
mw_geoNwInd(
mw_geoNwSecPdu(
mdw_securedMessage_DENMs(?, ?, {
mw_trailer_field_signature
})
))){
tc_ac.stop;
log("*** " & testcasename() & ": INFO: DENM message with signature trailer received ***");
v_nbVerification := v_nbVerification + 1;
if (v_nbVerification < c_nbVerification) {
tc_ac.start;
repeat;
}
}
[] geoNetworkingPort.receive(
mw_geoNwInd(
mw_geoNwSecPdu(
mdw_securedMessage_DENMs(?, ?, {
mw_trailer_field_signature
})
))){
tc_ac.stop;
log("*** " & testcasename() & ": INFO: DENM message with signature trailer received ***");
v_nbVerification := v_nbVerification + 1;
if (v_nbVerification < c_nbVerification) {
tc_ac.start;
repeat;
}
}
[] geoNetworkingPort.receive(
mw_geoNwInd(
mw_geoNwSecPdu(
mdw_securedMessage_DENMs(?, ?, {})
mdw_securedMessage_DENMs(?, ?, {})
))) {
tc_ac.stop;
log("*** " & testcasename() & ": FAIL: DENM message with NO trailer fields received ***");
...
...
@@ -3335,8 +3336,8 @@ module AtsSecurity_TestCases {
[] geoNetworkingPort.receive(
mw_geoNwInd(
mw_geoNwSecPdu(
mdw_securedMessage_DENMs(?, ?,
superset( mw_trailer_field, ? )
mdw_securedMessage_DENMs(?, ?,
superset( mw_trailer_field, ? )
)))) {
tc_ac.stop;
log("*** " & testcasename() & ": FAIL: DENM message with more than one trailer field received ***");
...
...
@@ -3897,10 +3898,10 @@ module AtsSecurity_TestCases {
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
}
} else if (v_cert.validity_restrictions[v_counter].type_ == e_time_start_and_duration) {
if (PICS_PLUGTEST_VERSION){
if (PICS_PLUGTEST_VERSION){
log("*** " & testcasename() & ": FAIL: Usage of time_start_and_duration is not allowed in TS103097 v1.2.5");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
}
}
v_startTime := v_cert.validity_restrictions[v_counter].validity.time_start_and_duration.start_validity * 1000000;
v_duration := f_duration2time(v_cert.validity_restrictions[v_counter].validity.time_start_and_duration.duration_) * 1000000;
if (v_generationTime < v_startTime or (v_startTime + v_duration) > v_endTime ) {
...
...
@@ -4935,10 +4936,10 @@ module AtsSecurity_TestCases {
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
}
if (v_si.type_ != e_certificate_digest_with_sha256) {
if (v_si.type_ != e_certificate_digest_with_other_algorithm or PICS_PLUGTEST_VERSION) {
log("*** " & testcasename() & ": FAIL: Certificate is not signed with digest ***");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
}
if (v_si.type_ != e_certificate_digest_with_other_algorithm or PICS_PLUGTEST_VERSION) {
log("*** " & testcasename() & ": FAIL: Certificate is not signed with digest ***");
f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
}
}
// signer_info.type indicates 'certificate_digest_with_sha256' or 'certificate_digest_with_other_algorythm'
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment