Newer
Older
/**
* @author ETSI / STF481
* @version $URL$
* $Id$
* @desc Module containing functions for Security Protocol
*
*/
module LibItsSecurity_Functions {
import from LibCommon_BasicTypesAndValues all;
garciay
committed
import from LibCommon_DataStrings all;
garciay
committed
// LibItsCommon
import from LibItsCommon_Functions all;
import from LibItsSecurity_TypesAndValues all;
garciay
committed
import from LibItsSecurity_Templates all;
import from LibItsSecurity_Pixits all;
import from LibItsSecurity_TestSystem all;
* @desc Produces a 256-bit (32-byte) hash value
* @param p_toBeHashedData Data to be used to calculate the hash value
* @return The hash value
*/
function f_hashWithSha256(
) return Oct32 {
return fx_hashWithSha256(p_toBeHashedData);
} // End of function f_hashWithSha256
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signaturee
* @param p_toBeSignedSecuredMessage The data to be signed
* @return The signature value
*/
function f_signWithEcdsaNistp256WithSha256(
) runs on ItsSecurityBaseComponent return octetstring {
return fx_signWithEcdsaNistp256WithSha256(
vc_signingPrivateKey
} // End of function f_signWithEcdsaNistp256WithSha256
* @desc Compute the HashedId8 value from the hash value
* @param p_hash The hash value
* @return The HashedId8 value
* @verdict
*/
function f_HashedId8FromSha256(
) return HashedId8 {
return substr(p_hash, lengthof(p_hash) - 8, 8);
* @desc Compute the HashedId3 value from the HashedId8 value
* @param p_hashp_hashedId8 The HashedId8 value
* @return The HashedId3 value
* @verdict Unchanged
*/
function f_HashedId3FromHashedId8 (
) return HashedId3 {
return substr(p_hashedId8, lengthof(p_hashedId8) - 3, 3);
} // End of function f_HashedId3FromHashedId8
* @desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_signature The signature
* @param p_ecdsaNistp256PublicKeyX The public key (x coordinate)
* @param p_ecdsaNistp256PublicKeyY The public key (y coordinate)
* @return true on success, false otherwise
*/
garciay
committed
function f_verifyWithEcdsaNistp256WithSha256(
in octetstring p_toBeVerifiedData,
in octetstring p_signature,
in octetstring p_ecdsaNistp256PublicKeyX,
in octetstring p_ecdsaNistp256PublicKeyY
) return boolean {
return fx_verifyWithEcdsaNistp256WithSha256(
p_toBeVerifiedData,
p_signature,
p_ecdsaNistp256PublicKeyX,
p_ecdsaNistp256PublicKeyY);
} // End of function f_verifyWithEcdsaNistp256WithSha256
* @desc Calculate digest over the certificate
* @param p_cert The certificate
* @return the digest
* @see Draft ETSI TS 103 097 V1.1.6 Clause 4.2.13 HashedId8
*/
function f_calculateDigestFromCertificate(
) return HashedId8 {
var octetstring v_toBeHashedData;
var octetstring v_hash;
var integer v_counter;
// Search for digest in the signer_infos field first
for (v_counter := 0; v_counter < lengthof(p_cert.signer_infos); v_counter := v_counter + 1) {
if (p_cert.signer_infos[v_counter].type_ == e_certificate_digest_with_ecdsap256) {
return p_cert.signer_infos[v_counter].signerInfo.digest;
}
} // End of 'for' statement
log ("f_calculateDigestFromCertificate: Not found in certificate, compute it");
v_toBeHashedData := bit2oct(encvalue(p_cert));
v_hash := f_hashWithSha256(v_toBeHashedData);
return substr(v_hash, lengthof(v_hash) - 8, 8);
* @desc Build a template of a secured beacon to be used for the Test Adapter secured beaconing processing
*/
function f_buildSecuredMessagePayloadToBeSigned(
) runs on ItsSecurityBaseComponent return ToBeSignedSecuredMessage {
var template (value) ToBeSignedSecuredMessage v_toBeSignedSecuredMessage;
if (p_includeCertificate == true) {
v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
c_security_profileOthers,
{ // Field HeaderFields
m_header_field_signer_info(
m_signerInfo_certificate(
vc_atCertificate
) // End of template m_signerInfo_certificate
), // End of template m_header_field_signer_info
m_header_field_generation_time(oct2int('BBBBBBBB'O)), // To be replaced by TA with generation time
m_header_field_generation_location(
)
}, // End of field HeaderFields
{
m_payload_unsecured(
'AAAAAAAAAA'O // To be replaced by TA with real payload
)
}, // End of field HeaderFields
e_signature
);
} else {
v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
c_security_profileOthers,
{ // Field HeaderFields
m_header_field_signer_info(
m_signerInfo_digest(
vc_atCertificate.signer_infos[0].signerInfo.digest
) // End of template m_signerInfo_certificate
), // End of template m_header_field_signer_info
m_header_field_generation_time(oct2int('BBBBBBBB'O)), // To be replaced by TA with generation time
m_header_field_generation_location(
)
}, // End of field HeaderFields
{
m_payload_unsecured(
'AAAAAAAAAA'O // To be replaced by TA with real payload
)
}, // End of field HeaderFields
e_signature
);
}
* @desc This function build and sign the SecureMessage part covered by the signature process
* @param p_securedMessage The signed SecureMessage part
* @param p_unsecuredPayload The unsigned payload (e.g. a beacon)
* @param p_signerInfoType Add digest or AT certificate or certificate chain
* @param p_headerFields HeaderFields to be inserted in the message
* @param p_configId The configuration identifier to be used
* @param p_addMissingHeaders Whether to add mandatory headers not present in p_headerFields
* @param p_certificateName The certificate identifier to be used. Default: TA_CONFIG_A
* @return true on success, false otherwise
* @verdict Unchanged
*/
out template (value) SecuredMessage p_securedMessage,
in octetstring p_unsecuredPayload,
in template (omit) SignerInfoType p_signerInfoType := e_certificate_digest_with_ecdsap256,
in template (omit) HeaderFields p_headerFields := omit,
in template (omit) charstring p_certificateName := omit,
in boolean p_addMissingHeaders := true
) runs on ItsSecurityBaseComponent return boolean {
var Certificate v_aaCertificate, v_atCertificate;
var octetstring v_secPayload, v_signature;
var Oct32 v_hash;
var template (value) ToBeSignedSecuredMessage v_toBeSignedSecuredMessage;
var integer i, j, k, n;
var HeaderFields v_mandatoryHeaders := {};
var template (value) HeaderFields v_headerFields := {};
var template (value) HeaderField v_signerInfo;
// Sanity check
if (ispresent(p_certificateName) and (p_certificateName != "TA_CONFIG_A")) {
if (f_readCertificate(p_certificateName & ".AA_CERT", v_aaCertificate) == false) {
return false;
}
if (f_readCertificate(p_certificateName & ".AT_CERT", v_atCertificate) == false) {
return false;
}
} else {
v_aaCertificate := vc_aaCertificate;
v_atCertificate := vc_atCertificate;
}
if(p_addMissingHeaders == false) {
v_toBeSignedSecuredMessage.header_fields := p_headerFields;
}
else {
// Prepare mandatory headers
if (p_signerInfoType == e_certificate) { // Add the AT certificate
v_signerInfo := m_header_field_signer_info(m_signerInfo_certificate(v_atCertificate));
}
if (p_signerInfoType == e_certificate_chain) { // Add the AT certificate + AA Certificate
v_signerInfo := m_header_field_signer_info(
m_signerInfo_certificates(
{
v_aaCertificate,
v_atCertificate
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
);
}
if (p_signerInfoType == e_certificate_digest_with_ecdsap256) { // Add the AT certificate digest
v_signerInfo := m_header_field_signer_info(m_signerInfo_digest(v_atCertificate.signer_infos[0].signerInfo.digest));
}
v_mandatoryHeaders := {
v_signerInfo,
m_header_field_generation_time(f_getCurrentTime()),
m_header_field_message_type(c_messageType_CAM)
}
if(not(ispresent(p_headerFields))) {
v_toBeSignedSecuredMessage.header_fields := v_mandatoryHeaders;
}
else {
// Merge p_headerFields and v_mandatoryHeaders into v_headerFields
i := 0; // index for p_headerFields
j := 0; // index for v_mandatoryHeaders
k := 0; // index for v_headerFields
// Special processing for signer_info
if(lengthof(p_headerFields) > 0 and p_headerFields[i].type_ == e_signer_info) {
v_headerFields[k] := p_headerFields[i];
k := k + 1;
i := i + 1;
}
for(j:=j; j < lengthof(v_mandatoryHeaders); j:=j+1) {
// Search for mandatory header in p_HeaderFields
for(n:=0; n < lengthof(p_headerFields); n:=n+1) {
if(p_headerFields[n].type_ == v_mandatoryHeaders[j].type_) {
// mandatory header already in p_HeaderFields
break;
}
}
if(n >= lengthof(p_headerFields)) {
if(v_mandatoryHeaders[j].type_ != e_signer_info) {
// Add headers from p_headerFields having lower number than mandatory header
for(n:=i ; n < lengthof(p_headerFields) and p_headerFields[n].type_ < v_mandatoryHeaders[j].type_; n:=n+1) {
v_headerFields[k] := p_headerFields[n];
k := k + 1;
i := i + 1;
}
// Add mandatory header
v_headerFields[k] := v_mandatoryHeaders[j];
k := k + 1;
j := j + 1;
}
}
// Add remaining headers from p_HeaderFields
for(i:=i; i < lengthof(p_headerFields); i:=i+1) {
// Add headers from p_headerFields having lower number than mandatory header
v_headerFields[k] := p_headerFields[i];
k := k + 1;
}
}
v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
c_security_profileCAMs,
v_headerFields,
{
m_payload_unsecured(
p_unsecuredPayload
)
}, // End of field HeaderFields
e_signature
);
v_secPayload := bit2oct(encvalue(v_toBeSignedSecuredMessage));
// Calculate the hash of the SecuredMessage payload to be signed
v_hash := f_hashWithSha256(v_secPayload);
// Signed payload
v_signature := f_signWithEcdsaNistp256WithSha256(
v_hash
);
p_securedMessage := md_secureMessage_profileCam( // See Clause 7.1 Security profile for CAMs
v_toBeSignedSecuredMessage.header_fields,
v_toBeSignedSecuredMessage.payload_fields,
{
m_trailer_field_signature(
m_signature(
m_ecdsaSignature(
m_eccPointecdsa_nistp256_with_sha256_y_coordinate_only(
substr(v_signature, 2, 32)
),
substr(v_signature, 34, 32)
)
); // End of template m_securedMessage_profileCam
* @desc This function build and sign the SecureMessage part covered by the signature process
* @param p_securedMessage The signed SecureMessage part
* @param p_unsecuredPayload The unsigned payload (e.g. a beacon)
* @param p_threeDLocation The ThreeDLocation value
* @param p_addCertificate Set to true to add the AT certificate in header fields. Otherwise, only the AA certificate digest will be added
* @param p_headerFields Additional HeaderFields
* @return true on success, false otherwise
* @verdict Unchanged
*/
out template (value) SecuredMessage p_securedMessage,
in octetstring p_unsecuredPayload,
in ThreeDLocation p_threeDLocation,
in template (omit) boolean p_addCertificate := false,
in template (omit) HeaderFields p_headerFields := omit
) runs on ItsSecurityBaseComponent return boolean {
// Local variables
var octetstring v_secPayload, v_signature;
var Oct32 v_hash;
var template (value) ToBeSignedSecuredMessage v_toBeSignedSecuredMessage;
// Create SecuredMessage payload to be signed
if (valueof(p_addCertificate) == true) { // Add the AA certificate
v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
c_security_profileDENMs,
{ // Field HeaderFields
m_header_field_signer_info(
m_signerInfo_certificate(
vc_atCertificate
) // End of template m_signerInfo_certificate
), // End of template m_header_field_signer_info
m_header_field_generation_time(f_getCurrentTime()),
m_header_field_generation_location(
p_threeDLocation
),
m_header_field_message_type(c_messageType_DENM)
}, // End of field HeaderFields
{
m_payload_unsecured(
p_unsecuredPayload
)
}, // End of field HeaderFields
e_signature
);
} else { // Add the AA certificate digest
v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
c_security_profileDENMs,
{ // Field HeaderFields
m_header_field_signer_info(
m_signerInfo_digest(
vc_atCertificate.signer_infos[0].signerInfo.digest
), // End of template m_header_field_digest
m_header_field_generation_time(f_getCurrentTime()),
m_header_field_generation_location(
p_threeDLocation
),
m_header_field_message_type(c_messageType_DENM)
}, // End of field HeaderFields
{
m_payload_unsecured(
p_unsecuredPayload
)
}, // End of field HeaderFields
e_signature
);
}
// Add additional header fields if any
if (ispresent(p_headerFields) == true) {
var integer v_addItemIndex := lengthof(v_toBeSignedSecuredMessage.header_fields);
var integer v_counter;
for (v_counter := 0; v_counter < lengthof(p_headerFields); v_counter := v_counter + 1) {
v_toBeSignedSecuredMessage.header_fields[v_addItemIndex] := p_headerFields[v_counter];
v_addItemIndex := v_addItemIndex + 1;
} // End of 'for' statement
}
log("v_toBeSignedSecuredMessage= ", v_toBeSignedSecuredMessage);
v_secPayload := bit2oct(encvalue(v_toBeSignedSecuredMessage));
// Calculate the hash of the SecuredMessage payload to be signed
v_hash := f_hashWithSha256(v_secPayload);
// Signed payload
v_signature := f_signWithEcdsaNistp256WithSha256(
v_hash
);
p_securedMessage := md_secureMessage_profileDenm( // See Clause 7.2 Security profile for DENMs
v_toBeSignedSecuredMessage.header_fields,
v_toBeSignedSecuredMessage.payload_fields,
{
m_trailer_field_signature(
m_signature(
m_ecdsaSignature(
m_eccPointecdsa_nistp256_with_sha256_y_coordinate_only(
substr(v_signature, 2, 32)
),
substr(v_signature, 34, 32)
)
); // End of template m_securedMessage_profileDenm
return true;
} // End of function f_buildGnSecuredDenm
garciay
committed
* @desc This function build and sign the SecureMessage part covered by the signature process
* @param p_securedMessage The signed SecureMessage part
* @param p_unsecuredPayload The unsigned payload (e.g. a beacon)
* @param p_threeDLocation The ThreeDLocation value
* @param p_addCertificate Set to true to add the AT certificate in header fields. Otherwise, only the AA certificate digest will be added
* @param p_headerFields Additional HeaderFields
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_buildGnSecuredOtherMessage(
out template (value) SecuredMessage p_securedMessage,
in octetstring p_unsecuredPayload,
in ThreeDLocation p_threeDLocation,
in template (omit) boolean p_addCertificate := false,
in template (omit) HeaderFields p_headerFields := omit
) runs on ItsSecurityBaseComponent return boolean {
// Local variables
var octetstring v_secPayload, v_signature;
var Oct32 v_hash;
var template (value) ToBeSignedSecuredMessage v_toBeSignedSecuredMessage;
// Create SecuredMessage payload to be signed
if (valueof(p_addCertificate) == true) { // Add the AA certificate
v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
c_security_profileOthers,
{ // Field HeaderFields
m_header_field_signer_info(
m_signerInfo_certificate(
vc_atCertificate
) // End of template m_signerInfo_certificate
), // End of template m_header_field_signer_info
m_header_field_generation_time(f_getCurrentTime()),
m_header_field_generation_location(
p_threeDLocation
)
}, // End of field HeaderFields
{
m_payload_unsecured(
p_unsecuredPayload
)
}, // End of field HeaderFields
e_signature
);
} else { // Add the AA certificate digest
v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
c_security_profileOthers,
{ // Field HeaderFields
m_header_field_signer_info(
m_signerInfo_digest(
vc_atCertificate.signer_infos[0].signerInfo.digest
), // End of template m_header_field_digest
m_header_field_generation_time(f_getCurrentTime()),
m_header_field_generation_location(
p_threeDLocation
)
}, // End of field HeaderFields
{
m_payload_unsecured(
p_unsecuredPayload
)
}, // End of field HeaderFields
e_signature
);
}
// Add additional header fields if any
if (ispresent(p_headerFields) == true) {
var integer v_addItemIndex := lengthof(v_toBeSignedSecuredMessage.header_fields);
var integer v_counter;
for (v_counter := 0; v_counter < lengthof(p_headerFields); v_counter := v_counter + 1) {
v_toBeSignedSecuredMessage.header_fields[v_addItemIndex] := p_headerFields[v_counter];
v_addItemIndex := v_addItemIndex + 1;
} // End of 'for' statement
}
log("v_toBeSignedSecuredMessage= ", v_toBeSignedSecuredMessage);
v_secPayload := bit2oct(encvalue(v_toBeSignedSecuredMessage));
// Calculate the hash of the SecuredMessage payload to be signed
v_hash := f_hashWithSha256(v_secPayload);
// Signed payload
v_signature := f_signWithEcdsaNistp256WithSha256(
v_hash
);
p_securedMessage := md_securedMessage_profileOther( // See Clause 7.3 Generic security profile for other signed messages
v_toBeSignedSecuredMessage.header_fields,
v_toBeSignedSecuredMessage.payload_fields,
{
m_trailer_field_signature(
m_signature(
m_ecdsaSignature(
m_eccPointecdsa_nistp256_with_sha256_y_coordinate_only(
substr(v_signature, 2, 32)
),
substr(v_signature, 34, 32)
)
garciay
committed
)
)
); // End of template md_securedMessage_profileOther
return true;
} // End of function f_buildGnSecuredOtherMessage
} // End of group hostSignatureHelpers
group deviceSignatureHelpers {
* @desc Verify the signature of the provided certificate
* @param p_certificateToBeVerified Certificate to be verified
* @param p_publicKey Public key to verify the certificate signature
* @return true on success, false otherwise
* @verdict
*/
in template (value) Certificate p_certificateToBeVerified,
in template (value) PublicKey p_publicKey
var octetstring toBeVerifiedData;
var octetstring v_signature;
var template (value) ToBeSignedCertificate v_toBeSignedCertificate;
// Create Certificate payload to be verified
v_toBeSignedCertificate := m_toBeSignedCertificate(p_certificateToBeVerified);
toBeVerifiedData := bit2oct(encvalue(v_toBeSignedCertificate));
// Build the signature
v_signature :=
'0000'O &
valueof(p_certificateToBeVerified.signature_.signature_.ecdsa_signature.r.x) &
valueof(p_certificateToBeVerified.signature_.signature_.ecdsa_signature.s);
// Verify the certificate
v_result := f_verifyWithEcdsaNistp256WithSha256(
toBeVerifiedData,
v_signature,
valueof(p_publicKey.public_key.eccPoint.x),
valueof(p_publicKey.public_key.eccPoint.y.y)
} // End of finction f_verifyCertificateSignatureWithPublicKey
* @desc Verify the signature of the provided secured message
* @param p_certificateToBeVerified Certificate to be verified
* @param p_issuingCertificate Issuing certificate
* @return true on success, false otherwise
* @verdict
*/
function f_verifyCertificateSignatureWithIssuingCertificate(
in template (value) Certificate p_certificateToBeVerified,
in template (value) Certificate p_issuingCertificate
var integer v_counter;
for (v_counter := 0; v_counter < lengthof(p_issuingCertificate.subject_attributes); v_counter := v_counter + 1) {
if (valueof(p_issuingCertificate.subject_attributes[v_counter].type_) == e_verification_key) {
return f_verifyCertificateSignatureWithPublicKey(
p_certificateToBeVerified,
p_issuingCertificate.subject_attributes[v_counter].attribute.key);
}
} // End of 'for' statement
return false;
} // End of function f_verifyCertificateSignatureWithIssuingCertificate
* @desc Verify the signature of the provided secured message
* @param p_securedMessage The message to be verified
* @param p_publicKey The ECDSA public key to verify a signature
* @param p_certificate Certificate to be used to verify the message
* @return true on success, false otherwise
* @verdict
*/
function f_verifyGnSecuredMessageSignatureWithPublicKey(
in template (value) SecuredMessage p_securedMessage,
in template (value) PublicKey p_publicKey
) return boolean {
// Local variables
var octetstring v_secPayload;
var octetstring v_signedData;
var Oct32 v_hash;
var integer v_counter;
var boolean v_result := false;
var template (value) ToBeSignedSecuredMessage v_toBeSignedSecuredMessage;
// log(">>> f_verifyGnSecuredMessageSignatureWithPublicKey: ", p_securedMessage);
// Create SecuredMessage payload to be signed
v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
p_securedMessage.header_fields,
p_securedMessage.payload_fields,
v_secPayload := bit2oct(encvalue(v_toBeSignedSecuredMessage));
// log("f_verifyGnSecuredMessageSignatureWithPublicKey: v_secPayload=", v_secPayload);
// Calculate the hash of the SecuredMessage payload to be signed
v_hash := fx_hashWithSha256(v_secPayload);
// log("f_verifyGnSecuredMessageSignatureWithPublicKey: v_hash=", v_hash);
// Verify payload
for (v_counter := 0; v_counter < lengthof(p_securedMessage.trailer_fields); v_counter := v_counter + 1) {
var SecuredMessage v_securedMessage := valueof(p_securedMessage);
(v_securedMessage.trailer_fields[v_counter].type_ == e_signature) and
(v_securedMessage.trailer_fields[v_counter].trailerField.signature_.algorithm == e_ecdsa_nistp256_with_sha256)
v_signedData :=
'0000'O &
v_securedMessage.trailer_fields[v_counter].trailerField.signature_.signature_.ecdsa_signature.r.x &
v_securedMessage.trailer_fields[v_counter].trailerField.signature_.signature_.ecdsa_signature.s;
// log("f_verifyGnSecuredMessageSignatureWithPublicKey: v_signedData=", v_signedData);
v_result := f_verifyWithEcdsaNistp256WithSha256(
v_hash,
v_signedData,
valueof(p_publicKey.public_key.eccPoint.x),
valueof(p_publicKey.public_key.eccPoint.y.y)
}
} // End of 'for' statement
// log("f_verifyGnSecuredMessageSignatureWithPublicKey: v_result=", v_result);
} // End of function f_verifyCertificateSignatureWithPublicKey
/**
* @desc Verify the signature of the provided secured message
* @param p_securedMessage
* @param p_certificate Certificate to be used to verify the message
* @return true on success, false otherwise
* @verdict
*/
function f_verifyGnSecuredMessageSignatureWithCertificate(
in template (value) SecuredMessage p_securedMessage,
in template (value) Certificate p_certificate
var integer v_counter;
for (v_counter := 0; v_counter < lengthof(p_certificate.subject_attributes); v_counter := v_counter + 1) {
var SubjectAttribute v_subjectAttribute := valueof(p_certificate.subject_attributes[v_counter]);
// log("f_verifyGnSecuredMessageSignatureWithCertificate: processing ", v_subjectAttribute);
if (v_subjectAttribute.type_ == e_verification_key) {
// if (valueof(p_certificate.subject_attributes[v_counter].type_) == e_verification_key) {
return f_verifyGnSecuredMessageSignatureWithPublicKey(
p_securedMessage,
p_certificate.subject_attributes[v_counter].attribute.key);
}
} // End of 'for' statement
return false;
} // End of function f_verifyGnSecuredOtherMessageWithDeviceCertificate
} // End of group deviceSignatureHelpers
garciay
committed
* @desc return SecuredMessage header field of given type or null if none
* @param p_msg the SecuredMessage
* @param p_type header field type
* @return HeaderField of given type if any or null
*/
in SecuredMessage p_securedMessage,
in HeaderFieldType p_headerFieldType,
out HeaderField p_return
) return boolean {
var integer v_length := lengthof(p_securedMessage.header_fields);
for (var integer i := 0; i < v_length; i := i + 1) {
if (p_securedMessage.header_fields[i].type_ == p_headerFieldType) {
p_return := p_securedMessage.header_fields[i];
log("f_getMsgHeaderField: return false");
* @desc return SignerInfo SecuredMessage field
*/
function f_getMsgSignerInfo (
in SecuredMessage p_securedMessage,
out SignerInfo p_signerInfo
) return boolean {
var HeaderField v_hf;
if (f_getMsgHeaderField(p_securedMessage, e_signer_info, v_hf) == true) {
if (isbound(v_hf.headerField.signer)) {
p_signerInfo := v_hf.headerField.signer;
return true;
}
log("f_getMsgSignerInfo: return false");
}// End of group messageGetters
group certificateGetters {
* @desc Set the gneration location ase defined in Draft ETSI TS 103 097 V1.1.6
* @param p_latitude The latitude value
* @param p_longitude The longitude value
* @param p_elevation The elevation value
* @verdict Unchanged
*/
function f_setGenerationLocation(
in WGSLatitude p_latitude,
in WGSLongitude p_longitude,
in Oct2 p_elevation := '0000'O
) runs on ItsSecurityBaseComponent {
vc_location := {
p_elevation
}
} // End of function f_setGenerationLocation
* @desc Load in memory cache the certificates available
* @param p_configId A configuration identifier
* @remark This method SHALL be call before any usage of certificates
* @return true on success, false otherwise
*/
) runs on ItsSecurityBaseComponent return boolean {
var boolean v_result;
// Setup certificates memory cache
if (fx_loadCertificates(PX_ROOT_PATH_FOR_SECURITY, p_configId) == true) {
// Setup security component variables
f_readCertificate("TA_CONFIG_A.AA_CERT", vc_aaCertificate);
f_readCertificate("TA_CONFIG_A.AT_CERT", vc_atCertificate);
f_readPrivateKeys("TA_CONFIG_A.PRIVATE_KEYS", vc_signingPrivateKey, vc_encryptPrivateKey);
return true;
}
return false;
} // End of function f_loadCertificates
/**
* @desc Unload from memory cache the certificates available
* @return true on success, false otherwise
*/
function f_unloadCertificates() runs on ItsSecurityBaseComponent return boolean {
// Reset security component variables
vc_signingPrivateKey := '0000000000000000000000000000000000000000000000000000000000000000'O;
vc_encryptPrivateKey := '0000000000000000000000000000000000000000000000000000000000000000'O;
// Clear certificates memory cache
return fx_unloadCertificates();
} // End of function f_unloadCertificates
* @desc Read the specified certificate
* @param p_certificateId the certificate identifier
* @param p_certificate the expected certificate
* @return true on success, false otherwise
*/
in charstring p_certificateId,
out Certificate p_certificate
) runs on ItsSecurityBaseComponent return boolean {
var octetstring v_certificate;
if (fx_readCertificate(p_certificateId, v_certificate) == true) {
var integer v_result := decvalue(oct2bit(v_certificate), p_certificate);
if (v_result == 0) {
return true;
}
}
return false;
} // End of function f_readCertificate
/**
* @desc Read the private keys for the specified certificate
* @param p_keysId the keys identifier
* @param p_signingPrivateKey the signing private key
* @param p_encryptPrivateKey the encrypt private key
* @return true on success, false otherwise
*/
function f_readPrivateKeys(
in charstring p_keysId,
out Oct32 p_signingPrivateKey,
out Oct32 p_encryptPrivateKey
) runs on ItsSecurityBaseComponent return boolean {
return fx_readPrivateKeys(p_keysId, p_signingPrivateKey, p_encryptPrivateKey);
} // End of function f_readPrivateKeys
function f_getCertificateValidityRestriction(
in template (value) Certificate p_cert,
in ValidityRestrictionType p_type,
out ValidityRestriction p_return
) return boolean {
for (var integer i := 0; i < lengthof(p_cert.validity_restrictions); i := i + 1) {
if (valueof(p_cert).validity_restrictions[i].type_ == p_type ) {
p_return := valueof(p_cert).validity_restrictions[i];
return true;
} // End of function f_getCertificateValidityRestriction
function f_getCertificateSignerInfo (
in template (value) Certificate p_cert,
out SignerInfo p_si
) return boolean {
and lengthof(p_cert.signer_infos) > 0) {
p_si := valueof(p_cert).signer_infos[0];
return true;
function f_getCertificateSubjectAttribute(
in template (value) Certificate p_cert,
in SubjectAttributeType p_type,
out SubjectAttribute p_return
) return boolean {
for (var integer i := 0; i < lengthof(p_cert.subject_attributes); i := i + 1) {
if (valueof(p_cert).subject_attributes[i].type_ == p_type ) {
p_return := valueof(p_cert).subject_attributes[i];
return true;
}
}
return false;
}
} // End of group helpersFunctions
* @desc Produces a 256-bit (32-byte) hash value
* @param p_toBeHashedData Data to be used to calculate the hash value
* @return The hash value
*/
external function fx_hashWithSha256(in octetstring p_toBeHashedData) return Oct32;
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signaturee
* @param p_toBeSignedSecuredMessage The data to be signed
* @param p_privateKey The private key
* @return The signature value
*/
external function fx_signWithEcdsaNistp256WithSha256(in octetstring p_toBeSignedSecuredMessage, in octetstring/*UInt64*/ p_privateKey) return octetstring;
/**
* @desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_signature The signature
* @param p_ecdsaNistp256PublicKeyX The public key (x coordinate)
* @param p_ecdsaNistp256PublicKeyY The public key (y coordinate)
* @return true on success, false otherwise
*/
external function fx_verifyWithEcdsaNistp256WithSha256(in octetstring p_toBeVerifiedData, in octetstring p_signature, in octetstring p_ecdsaNistp256PublicKeyX, in octetstring p_ecdsaNistp256PublicKeyY) return boolean;
/**
* @desc Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm.
* This function should not be used by the ATS
* @param p_privateKey The new private key value
* @param p_publicKeyX The new public key value (x coordinate)
* @param p_publicKeyX The new public key value (y coordinate)
* @return true on success, false otherwise
*/
external function fx_generateKeyPair(out octetstring/*UInt64*/ p_privateKey, out octetstring p_publicKeyX, out octetstring p_publicKeyY) return boolean;
} // End of group signing
group encryption {
} // End of group encryption
group certificatesLoader {
/**
* @desc Load in memory cache the certificates available in the specified directory
* @param p_rootDirectory Root directory to access to the certificates identified by the certificate ID
* @param p_configId A configuration identifier
* @remark This method SHALL be call before any usage of certificates
* @return true on success, false otherwise
*/
external function fx_loadCertificates(in charstring p_rootDirectory, in charstring p_configId) return boolean;
/**
* @desc Unload from memory cache the certificates
* @return true on success, false otherwise
*/
external function fx_unloadCertificates() return boolean;
* @desc Read the specified certificate
* @param p_certificateId the certificate identifier
* @param p_certificate the expected certificate
* @return true on success, false otherwise
*/
external function fx_readCertificate(in charstring p_certificateId, out octetstring p_certificate) return boolean;
/**
* @desc Read the private keys for the specified certificate
* @param p_keysId the keys identifier
* @param p_signingPrivateKey the signing private key
* @param p_encryptPrivateKey the encrypt private key
* @return true on success, false otherwise
*/
external function fx_readPrivateKeys(in charstring p_keysId, out Oct32 p_signingPrivateKey, out Oct32 p_encryptPrivateKey) return boolean;
} // End of group certificatesLoader
* @desc Check that given polygon doesn't have neither self-intersections nor holes.
* @param p_region Polygonal Region
* @return true on success, false otherwise
* @verdict Unchanged
*/
external function fx_isValidPolygonalRegion(in PolygonalRegion p_region) return boolean;