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;
/**
* @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(
in octetstring p_toBeHashedData
) 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(in Oct32 p_toBeSignedSecuredMessage) return octetstring {
return fx_signWithEcdsaNistp256WithSha256(
p_toBeSignedSecuredMessage,
PX_TA_CONFIGS[PX_CERTIFICATE_CONFIG_IDX].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(
in Oct32 p_hash
) return HashedId8 {
return substr(p_hash, lengthof(p_hash) - 8, 8);
} // End of function f_HashedId8FromSha256
/**
* @desc Compute the HashedId3 value from the HashedId8 value
* @param p_hashp_hashedId8 The HashedId8 value
* @return The HashedId3 value
* @verdict
*/
function f_HashedId3FromHashedId8 (
in HashedId8 p_hashedId8
) 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
* @return the digest
* @see Draft ETSI TS 103 097 V1.1.6 Clause 4.2.13 HashedId8
function f_calculateDigestFromCertificate(
in Certificate p_cert
) 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
// digest not found, 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()
return ToBeSignedSecuredMessage {
var template (value) ToBeSignedSecuredMessage v_toBeSignedSecuredMessage;
v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
c_security_profileOthers,
{ // Field HeaderFields
m_header_field_signer_info(
m_signerInfo_certificate(
PX_TA_CONFIGS[PX_CERTIFICATE_CONFIG_IDX].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 current time
m_header_field_generation_location(
PX_TA_CONFIGS[PX_CERTIFICATE_CONFIG_IDX].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_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_buildGnSecuredCam(
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
) 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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
c_security_profileCAMs,
{ // Field HeaderFields
m_header_field_signer_info(
m_signerInfo_certificate(
PX_TA_CONFIGS[PX_CERTIFICATE_CONFIG_IDX].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_CAM)
}, // 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_profileCAMs,
{ // Field HeaderFields
m_header_field_signer_info(
m_signerInfo_digest(
PX_TA_CONFIGS[PX_CERTIFICATE_CONFIG_IDX].atCertificate.signer_infos[0].signerInfo.digest
) // End of template m_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_CAM)
}, // End of field HeaderFields
{
m_payload_unsecured(
p_unsecuredPayload
)
}, // End of field HeaderFields
e_signature
);
}
log("v_toBeSignedSecuredMessage=", v_toBeSignedSecuredMessage);
// 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
}
v_secPayload := bit2oct(encvalue(v_toBeSignedSecuredMessage));
log("v_secPayload= ", v_secPayload);
// Calculate the hash of the SecuredMessage payload to be signed
v_hash := f_hashWithSha256(v_secPayload);
// Signed payload
v_signature := f_signWithEcdsaNistp256WithSha256(
v_hash
);
log("v_signature= ", v_signature);
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
*/
function f_buildGnSecuredDenm(
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
) 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
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
c_security_profileDENMs,
{ // Field HeaderFields
m_header_field_signer_info(
m_signerInfo_certificate(
PX_TA_CONFIGS[PX_CERTIFICATE_CONFIG_IDX].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(
PX_TA_CONFIGS[PX_CERTIFICATE_CONFIG_IDX].atCertificate.signer_infos[0].signerInfo.digest
) // End of template m_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
) 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
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
c_security_profileOthers,
{ // Field HeaderFields
m_header_field_signer_info(
m_signerInfo_certificate(
PX_TA_CONFIGS[PX_CERTIFICATE_CONFIG_IDX].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(
PX_TA_CONFIGS[PX_CERTIFICATE_CONFIG_IDX].atCertificate.signer_infos[0].signerInfo.digest
) // End of template m_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
*/
function f_verifyCertificateSignatureWithPublicKey(
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 :=
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
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,
e_signature
);
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 template (value) 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 (valueof(p_securedMessage).header_fields[i].type_ == p_headerFieldType) {
p_return := valueof(p_securedMessage).header_fields[i];
return true;
}
/**
* @desc return SignerInfo SecuredMessage field
*/
function f_getMsgSignerInfo (
) return boolean {
var HeaderField v_hf;
if(f_getMsgHeaderField(p_securedMessage, e_signer_info, v_hf)){
if(isbound(v_hf.headerField.signer)){
p_signerInfo := v_hf.headerField.signer;
return true;
}
}// End of group messageGetters
group certificateGetters {
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;
function f_getCertificateSignerInfo (
in template (value) Certificate p_cert,
out SignerInfo p_si
) return boolean {
if( isbound(valueof(p_cert).signer_infos)
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
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
group signing {
/**
* @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 geodesic {
/**
* @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;
/**
* @desc Check if a polygonal regin is inside another one
* @param p_parent The main polygonal region
* @param p_region The polygonal region to be included
* @return true on success, false otherwise
* @verdict Unchanged
*/
external function fx_isPolygonalRegionInside(in PolygonalRegion p_parent, in PolygonalRegion p_region) return boolean;
/**
* @desc Check that the location is inside a circular region
* @param p_region The circular region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
external function fx_isLocationInsideCircularRegion(in CircularRegion p_region, in ThreeDLocation p_location) return boolean;
/**
* @desc Check that the location is inside a rectangular region
* @param p_region The rectangular region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
external function fx_isLocationInsideRectangularRegion(in RectangularRegions p_region, in ThreeDLocation p_location) return boolean;
/**
* @desc Check that the location is inside a polygonal region
* @param p_region The polygonal region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
external function fx_isLocationInsidePolygonalRegion(in PolygonalRegion p_region, in ThreeDLocation p_location) return boolean;
/**
* @desc Check if the location is inside an identified region
* @param p_region The identified region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
external function fx_isLocationInsideIdentifiedRegion(in IdentifiedRegion p_region, in ThreeDLocation p_location) return boolean;
} // End of group externalFunctions
group geometryFunctions {
/**
* @desc Check that given location is valid
* @param p_location location to be checked
* @return true on success, false otherwise
*/
function f_isValidTwoDLocation(
in template (value) TwoDLocation p_location
return
(valueof(p_location).longitude != c_maxLongitude + 1) and
(valueof(p_location).latitude != c_maxLatitude + 1);
} // End of function f_isValidTwoDLocation
/**
* @desc Check that two given rectanlular regions are intersected
* Note: Regions must be normalized(northwest.latitude >= southeast.latitude)
* TODO: Add case when
* @param p_r1 Region 1
* @param p_r2 Region 2
*
* @return true on success, false otherwise
*/
function f_isRectangularRegionsIntersected(in template (value) RectangularRegion p_r1,
in template (value) RectangularRegion p_r2
) return boolean {
return not ( valueof(p_r2).northwest.longitude > valueof(p_r1).southeast.longitude
or valueof(p_r2).southeast.longitude < valueof(p_r1).northwest.longitude
or valueof(p_r2).southeast.latitude > valueof(p_r1).northwest.latitude
or valueof(p_r2).northwest.latitude < valueof(p_r1).southeast.latitude);
} // End of function f_isRectangularRegionsIntersected
function f_isContinuousRectangularRegions(in template (value) RectangularRegions regions
) return boolean {
} // End of function f_isRectangularRegionsIntersected
/**
* @desc Check if a polygonal regin is inside another one
* @param p_parent The main polygonal region
* @param p_region The polygonal region to be included
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_isRectangularRegionsInside(in template (value) RectangularRegions p_parent,
in template (value) RectangularRegions p_region
) return boolean {
// TODO: convert rectangular regions to polygons and check polygons
return true;
} // End of function f_isRectangularRegionsInside
* @desc Check that given polygon doesn't have neither self-intersections nor holes.
* @param p_region Polygonal Region
* @return true on success, false otherwise
function f_isValidPolygonalRegion(
in template (value) PolygonalRegion p_region
// Sanity check
if (not isbound(p_region) or (lengthof(p_region) == 0)) {
return false;
}
return fx_isValidPolygonalRegion(valueof(p_region));
} // End of function f_isValidPolygonalRegion
/**
* @desc Check if a polygonal regin is inside another one
* @param p_parent The main polygonal region
* @param p_region The polygonal region to be included
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_isPolygonalRegionInside(in template (value) PolygonalRegion p_parent,
in template (value) PolygonalRegion p_region
) return boolean {
// TODO: call external function
return true;
} // End of function f_isPolygonalRegionInside
function f_isIdentifiedRegionInside(in template (value) UInt16 p_parent,
in template (value) UInt16 p_region
) return boolean {
// TODO: call external function
} // End of function f_isIdentifiedRegionInside
/**
* @desc Check that the location is inside a region
* @param p_region The region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_isLocationInsideRegion(in template (value) GeographicRegion p_region,
in template (value) ThreeDLocation p_location
) return boolean {
var boolean v_ret := false;
select (p_region.region_type) {
case (e_none) {
v_ret := true;
}
case (e_circle) {
v_ret := f_isLocationInsideCircularRegion(p_region.region.circular_region, p_location);
}
case (e_rectangle) {
v_ret := f_isLocationInsideRectangularRegion(p_region.region.rectangular_region, p_location);
}
case (e_polygon) {
v_ret := f_isLocationInsidePolygonalRegion(p_region.region.polygonal_region, p_location);
}
case (e_id) {
v_ret := f_isLocationInsideIdentifiedRegion(p_region.region.id_region, p_location);
}
case else {
v_ret := f_isLocationInsideOtherRegion(p_region.region.other_region, p_location);
}
}
} // End of function f_isLocationInsideRegion
/**
* @desc Check that the location is inside a circular region
* @param p_region The circular region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_isLocationInsideCircularRegion(in template (value) CircularRegion p_region,
in template (value) ThreeDLocation p_location
) return boolean {
// Sanity check
if (not isbound(p_region) or not isbound(p_location)) {
return false;
}
return fx_isLocationInsideCircularRegion(valueof(p_region), valueof(p_location));
} // End of function f_isLocationInsideCircularRegion
/**
* @desc Check that the location is inside a rectangular region
* @param p_region The rectangular region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_isLocationInsideRectangularRegion(in template (value) RectangularRegions p_region,
in template (value) ThreeDLocation p_location
) return boolean {