Newer
Older
* @author ETSI / STF481 / STF507 / STF517 / STF538
* @version $URL$
* $Id$
* @desc Module containing functions for Security Protocol
* @copyright ETSI Copyright Notification
* No part may be reproduced except as authorized by written permission.
* The copyright and the foregoing restriction extend to reproduction in all media.
* All rights reserved.
import from LibCommon_BasicTypesAndValues all;
garciay
committed
import from LibCommon_DataStrings all;
// LibIts
import from IEEE1609dot2BaseTypes language "ASN.1:1997" all;
import from IEEE1609dot2 language "ASN.1:1997" all;
import from EtsiTs103097Module language "ASN.1:1997" all;
garciay
committed
// LibItsCommon
import from LibItsCommon_Functions all;
import from LibItsCommon_TypesAndValues 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 384-bit (48-byte) hash value
* @param p_toBeHashedData Data to be used to calculate the hash value
* @return The hash value
*/
function f_hashWithSha384(
in octetstring p_toBeHashedData
) return Oct48 {
return fx_hashWithSha384(p_toBeHashedData);
} // End of function f_hashWithSha256
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
* @param p_toBeSignedSecuredMessage The data to be signed
* @return The signature value
*/
function f_signWithEcdsaNistp256WithSha256(
in octetstring p_toBeSignedSecuredMessage,
in HashedId8 p_certificateIssuer,
in Oct32 p_privateKey
return fx_signWithEcdsaNistp256WithSha256(
p_certificateIssuer,
} // End of function f_signWithEcdsaNistp256WithSha256
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
* @param p_toBeSignedSecuredMessage The data to be signed
* @param p_privateKey The private key
* @return The signature value
*/
function f_signWithEcdsaBrainpoolp256WithSha256(
in octetstring p_toBeSignedSecuredMessage,
in HashedId8 p_certificateIssuer,
return fx_signWithEcdsaBrainpoolp256WithSha256(
p_toBeSignedSecuredMessage,
p_certificateIssuer,
p_privateKey
);
} // End of function f_signWithEcdsaBrainpoolp256WithSha256
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
* @param p_toBeSignedSecuredMessage The data to be signed
* @param p_privateKey The private key
* @return The signature value
*/
function f_signWithEcdsaBrainpoolp384WithSha384(
in octetstring p_toBeSignedSecuredMessage,
in HashedId8 p_certificateIssuer,
return fx_signWithEcdsaBrainpoolp384WithSha384(
p_toBeSignedSecuredMessage,
p_certificateIssuer,
p_privateKey
);
} // End of function f_signWithEcdsaBrainpoolp384WithSha384
in octetstring p_encryptPrivateKey,
in EtsiTs103097Data p_encrypedSecuredMessage,
out EtsiTs103097Data p_decrypedSecuredMessage
) return boolean {
if (ischosen(p_encrypedSecuredMessage.content.encryptedData)) {
var PKRecipientInfo v_pKRecipientInfo;
var RecipientInfo v_recipientInfo := p_encrypedSecuredMessage.content.encryptedData.recipients[0];
// Check the private encryption key
if (not(isbound(p_encryptPrivateKey))) {
log("*** " & testcasename() & ":ERROR: Failed to load encryption private key ***");
return false;
}
if (ischosen(v_recipientInfo.certRecipInfo)) {
v_pKRecipientInfo := p_encrypedSecuredMessage.content.encryptedData.recipients[0].certRecipInfo;
// Read the certificate based on the recipientId
} else if (ischosen(v_recipientInfo.signedDataRecipInfo)) {
v_pKRecipientInfo := p_encrypedSecuredMessage.content.encryptedData.recipients[0].signedDataRecipInfo;
// Read the certificate based on the recipientId
log("*** " & testcasename() & ":ERROR: Unsupported RecipientInfo variant ***");
return false;
if (ischosen(v_pKRecipientInfo.encKey.eciesNistP256)) {
var octetstring v_decryptedSecuredMessage;
var SymmetricCiphertext v_ciphertext := p_encrypedSecuredMessage.content.encryptedData.ciphertext;
v_decryptedSecuredMessage := f_decryptWithEciesNistp256WithSha256(
v_pKRecipientInfo.encKey.eciesNistP256.v.uncompressedP256.x,
v_pKRecipientInfo.encKey.eciesNistP256.v.uncompressedP256.y,
v_pKRecipientInfo.encKey.eciesNistP256.c,
v_pKRecipientInfo.encKey.eciesNistP256.t,
v_ciphertext.aes128ccm.nonce
);
if (isbound(v_decryptedSecuredMessage)) {
var bitstring v_decode := oct2bit(v_decryptedSecuredMessage);
if (decvalue(v_decode, p_decrypedSecuredMessage) == 0) {
return true;
} else {
log("*** " & testcasename() & ":ERROR: Faild to decode secured message ***");
} else if (ischosen(v_pKRecipientInfo.encKey.eciesBrainpoolP256r1)) {
var octetstring v_decryptedSecuredMessage;
var SymmetricCiphertext v_ciphertext := p_encrypedSecuredMessage.content.encryptedData.ciphertext;
v_decryptedSecuredMessage := f_decryptWithEciesBrainpoolp256WithSha256(
v_ciphertext.aes128ccm.ccmCiphertext,
p_encryptPrivateKey,
v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.uncompressedP256.x,
v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.uncompressedP256.y,
v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.c,
v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.t,
v_ciphertext.aes128ccm.nonce
);
if (isbound(v_decryptedSecuredMessage)) {
var bitstring v_decode := oct2bit(v_decryptedSecuredMessage);
if (decvalue(v_decode, p_decrypedSecuredMessage) == 0) {
return true;
} else {
log("*** " & testcasename() & ":ERROR: Faild to decode secured message ***");
} else {
log("*** " & testcasename() & ":ERROR: Message not encrypted ***");
} // End of function f_decrypt
* @desc Produces a Elliptic Curve Digital Encrytion Algorithm (ECIES) encryption using Nist-P256 algorithm
* @param p_toBeEncryptedSecuredMessage The data to be encrypted
* @param p_recipientsPublicKeyX The Recipient's public encryption key X-coordinate
* @param p_recipientsPublicKeyY The Recipient's public encryption key Y-coordinate
* @param p_publicEphemeralKeyX The generated ephemeral key X-coordinate
* @param p_publicEphemeralKeyY The generated ephemeral key Y-coordinate
* @param p_encrypted_sym_key The encrypted AES 128 CCM symmetric key
* @param p_authentication_vector The tag of the AES 128 CCM symmetric key encryption
* @param p_nonce The nonce vector of the AES 128 CCM symmetric key encryption
* @see IEEE Std 1609.2-2017 Clause 5.3.5 Public key encryption algorithms: ECIES
* @see https://www.nominet.uk/researchblog/how-elliptic-curve-cryptography-encryption-works/
* @see http://digital.csic.es/bitstream/10261/32671/1/V2-I2-P7-13.pdf
*/
function f_encryptWithEciesNistp256WithSha256(
in octetstring p_toBeEncryptedSecuredMessage,
in Oct32 p_recipientsPublicKeyX,
in Oct32 p_recipientsPublicKeyY,
out Oct12 p_nonce
) return octetstring {
return fx_encryptWithEciesNistp256WithSha256(
p_recipientsPublicKeyX,
p_recipientsPublicKeyY,
p_publicEphemeralKeyX,
p_publicEphemeralKeyY,
p_encrypted_sym_key,
p_authentication_vector,
p_nonce
);
} // End of function f_encryptWithEciesNistp256WithSha256
/**
* @desc Produces a Elliptic Curve Digital Encrytion Algorithm (ECIES) decryption using Nist-P256 algorithm
* @param p_encryptedSecuredMessage The data to be decrypted
* @param p_publicEphemeralKeyX The generated ephemeral key X-coordinate
* @param p_publicEphemeralKeyY The generated ephemeral key Y-coordinate
* @param p_encrypted_sym_key The encrypted AES 128 CCM symmetric key
* @param p_authentication_vector The tag of the AES 128 CCM symmetric key encryption
* @param p_nonce The nonce vector of the AES 128 CCM symmetric key encryption
* @return The decrypted message
* @see IEEE Std 1609.2-2017 Clause 5.3.5 Public key encryption algorithms: ECIES
* @see https://www.nominet.uk/researchblog/how-elliptic-curve-cryptography-encryption-works/
* @see http://digital.csic.es/bitstream/10261/32671/1/V2-I2-P7-13.pdf
*/
function f_decryptWithEciesNistp256WithSha256(
in octetstring p_encryptedSecuredMessage,
in Oct32 p_privateEncKey,
in Oct32 p_publicEphemeralKeyX,
in Oct32 p_publicEphemeralKeyY,
in Oct16 p_encrypted_sym_key,
in Oct16 p_authentication_vector,
in Oct12 p_nonce
return fx_decryptWithEciesNistp256WithSha256(
p_encryptedSecuredMessage,
p_privateEncKey,
p_publicEphemeralKeyX,
p_publicEphemeralKeyY,
p_encrypted_sym_key,
p_authentication_vector,
p_nonce
);
} // End of function f_decryptWithEcdsaNistp256WithSha256
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
285
286
287
288
289
290
291
292
293
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
/**
* @desc Produces a Elliptic Curve Digital Encrytion Algorithm (ECIES) encryption using Brainpool-P256 algorithm
* @param p_toBeEncryptedSecuredMessage The data to be encrypted
* @param p_recipientsPublicKeyX The Recipient's public encryption key X-coordinate
* @param p_recipientsPublicKeyY The Recipient's public encryption key Y-coordinate
* @param p_publicEphemeralKeyX The generated ephemeral key X-coordinate
* @param p_publicEphemeralKeyY The generated ephemeral key Y-coordinate
* @param p_encrypted_sym_key The encrypted AES 128 CCM symmetric key
* @param p_authentication_vector The tag of the AES 128 CCM symmetric key encryption
* @param p_nonce The nonce vector of the AES 128 CCM symmetric key encryption
* @return The encrypted message
* @see IEEE Std 1609.2-2017 Clause 5.3.5 Public key encryption algorithms: ECIES
* @see https://www.nominet.uk/researchblog/how-elliptic-curve-cryptography-encryption-works/
* @see http://digital.csic.es/bitstream/10261/32671/1/V2-I2-P7-13.pdf
*/
function f_encryptWithEciesBrainpoolp256WithSha256(
in octetstring p_toBeEncryptedSecuredMessage,
in Oct32 p_recipientsPublicKeyX,
in Oct32 p_recipientsPublicKeyY,
out Oct32 p_publicEphemeralKeyX,
out Oct32 p_publicEphemeralKeyY,
out Oct16 p_encrypted_sym_key,
out Oct16 p_authentication_vector,
out Oct12 p_nonce
) return octetstring {
return fx_encryptWithEciesBrainpoolp256WithSha256(
p_toBeEncryptedSecuredMessage,
p_recipientsPublicKeyX,
p_recipientsPublicKeyY,
p_publicEphemeralKeyX,
p_publicEphemeralKeyY,
p_encrypted_sym_key,
p_authentication_vector,
p_nonce
);
} // End of function f_encryptWithEciesBrainpoolp256WithSha256
/**
* @desc Produces a Elliptic Curve Digital Encrytion Algorithm (ECIES) decryption using Brainpool-P256 algorithm
* @param p_encryptedSecuredMessage The data to be decrypted
* @param p_publicEphemeralKeyX The generated ephemeral key X-coordinate
* @param p_publicEphemeralKeyY The generated ephemeral key Y-coordinate
* @param p_encrypted_sym_key The encrypted AES 128 CCM symmetric key
* @param p_authentication_vector The tag of the AES 128 CCM symmetric key encryption
* @param p_nonce The nonce vector of the AES 128 CCM symmetric key encryption
* @return The decrypted message
* @see IEEE Std 1609.2-2017 Clause 5.3.5 Public key encryption algorithms: ECIES
* @see https://www.nominet.uk/researchblog/how-elliptic-curve-cryptography-encryption-works/
* @see http://digital.csic.es/bitstream/10261/32671/1/V2-I2-P7-13.pdf
*/
function f_decryptWithEciesBrainpoolp256WithSha256(
in octetstring p_encryptedSecuredMessage,
in Oct32 p_privateEncKey,
in Oct32 p_publicEphemeralKeyX,
in Oct32 p_publicEphemeralKeyY,
in Oct16 p_encrypted_sym_key,
in Oct16 p_authentication_vector,
in Oct12 p_nonce
) return octetstring {
return fx_decryptWithEciesBrainpoolp256WithSha256(
p_encryptedSecuredMessage,
p_privateEncKey,
p_publicEphemeralKeyX,
p_publicEphemeralKeyY,
p_encrypted_sym_key,
p_authentication_vector,
p_nonce
);
} // End of function f_decryptWithEcdsaBrainpoolp256WithSha256
* @desc Compute the HashedId8 value from the hash value
* @param p_hash The hash value
* @return The HashedId8 value
* @verdict
*/
) return HashedId8 {
return substr(p_hash, lengthof(p_hash) - 8, 8);
/**
* @desc Compute the HashedId8 value from the hash value
* @param p_hash The hash value
* @return The HashedId8 value
* @verdict
*/
function f_HashedId8FromSha384(
in Oct48 p_hash
) return HashedId8 {
return substr(p_hash, lengthof(p_hash) - 8, 8);
} // End of function f_HashedId8FromSha384
* @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(
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_certificateIssuer The digest of the certificate issuer
* @param p_ecdsaNistp256PublicKeyCompressed The compressed public key
* @param p_compressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
garciay
committed
function f_verifyWithEcdsaNistp256WithSha256(
in HashedId8 p_certificateIssuer,
in Oct32 p_ecdsaNistp256PublicKeyCompressed,
in integer p_compressedMode
) return boolean {
// log("f_verifyWithEcdsaNistp256WithSha256: toBeVerifiedData", p_toBeVerifiedData);
// log("f_verifyWithEcdsaNistp256WithSha256: toBeVerifiedData length", lengthof(p_toBeVerifiedData));
// log("f_verifyWithEcdsaNistp256WithSha256: signature", p_signature);
// log("f_verifyWithEcdsaNistp256WithSha256: ecdsaNistp256PublicKeyCompressed", p_ecdsaNistp256PublicKeyCompressed);
return fx_verifyWithEcdsaNistp256WithSha256(
p_toBeVerifiedData,
p_certificateIssuer,
p_signature,
p_ecdsaNistp256PublicKeyCompressed,
p_compressedMode
);
} // End of function f_verifyWithEcdsaNistp256WithSha256
/**
* @desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The digest of the certificate issuer
* @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
*/
function f_verifyWithEcdsaNistp256WithSha256_1( // TODO To be removed
in octetstring p_toBeVerifiedData,
in HashedId8 p_certificateIssuer,
in octetstring p_signature,
in Oct32 p_ecdsaNistp256PublicKeyX,
in Oct32 p_ecdsaNistp256PublicKeyY
) return boolean {
// log("f_verifyWithEcdsaNistp256WithSha256: toBeVerifiedData", p_toBeVerifiedData);
// log("f_verifyWithEcdsaNistp256WithSha256: toBeVerifiedData length", lengthof(p_toBeVerifiedData));
// log("f_verifyWithEcdsaNistp256WithSha256: signature", p_signature);
// log("f_verifyWithEcdsaNistp256WithSha256: ecdsaNistp256PublicKeyX", p_ecdsaNistp256PublicKeyX);
// log("f_verifyWithEcdsaNistp256WithSha256: ecdsaNistp256PublicKeyY", p_ecdsaNistp256PublicKeyY);
return fx_verifyWithEcdsaNistp256WithSha256_1(
p_certificateIssuer,
p_ecdsaNistp256PublicKeyY);
} // End of function f_verifyWithEcdsaNistp256WithSha256_1
/**
* @Desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The digest of the certificate issuer
* @param p_ecdsaBrainpoolp256PublicKeyCompressed The compressed public key
* @param p_compressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
function f_verifyWithEcdsaBrainpoolp256WithSha256(
in octetstring p_toBeVerifiedData,
in HashedId8 p_certificateIssuer,
in Oct32 p_ecdsaBrainpoolp256PublicKeyCompressed,
in integer p_compressedMode
) return boolean {
// log("f_verifyWithEcdsaBrainpoolp256WithSha256: toBeVerifiedData", p_toBeVerifiedData);
// log("f_verifyWithEcdsaBrainpoolp256WithSha256: toBeVerifiedData length", lengthof(p_toBeVerifiedData));
// log("f_verifyWithEcdsaBrainpoolp256WithSha256: signature", p_signature);
// log("f_verifyWithEcdsaBrainpoolp256WithSha256: ecdsaBrainpoolp256PublicKeyCompressed", p_ecdsaBrainpoolp256PublicKeyCompressed);
return fx_verifyWithEcdsaBrainpoolp256WithSha256(
p_toBeVerifiedData,
p_certificateIssuer,
p_signature,
p_ecdsaBrainpoolp256PublicKeyCompressed,
p_compressedMode
);
} // End of function f_verifyWithEcdsaBrainpoolp256WithSha256
/**
* @Desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The digest of the certificate issuer
* @param p_signature The signature
* @param p_ecdsaBrainpoolp256PublicKeyX The public key (x coordinate)
* @param p_ecdsaBrainpoolp256PublicKeyY The public key (y coordinate)
* @return true on success, false otherwise
*/
function f_verifyWithEcdsaBrainpoolp256WithSha256_1( // TODO To be removed
in octetstring p_toBeVerifiedData,
in HashedId8 p_certificateIssuer,
in octetstring p_signature,
in Oct32 p_ecdsaBrainpoolp256PublicKeyX,
in Oct32 p_ecdsaBrainpoolp256PublicKeyY
) return boolean {
// log("f_verifyWithEcdsaBrainpoolp256WithSha256: toBeVerifiedData", p_toBeVerifiedData);
// log("f_verifyWithEcdsaBrainpoolp256WithSha256: toBeVerifiedData length", lengthof(p_toBeVerifiedData));
// log("f_verifyWithEcdsaBrainpoolp256WithSha256: signature", p_signature);
// log("f_verifyWithEcdsaBrainpoolp256WithSha256: ecdsaBrainpoolp256PublicKeyX", p_ecdsaBrainpoolp256PublicKeyX);
// log("f_verifyWithEcdsaBrainpoolp256WithSha256: ecdsaBrainpoolp256PublicKeyY", p_ecdsaBrainpoolp256PublicKeyY);
return fx_verifyWithEcdsaBrainpoolp256WithSha256_1(
p_certificateIssuer,
p_signature,
p_ecdsaBrainpoolp256PublicKeyX,
p_ecdsaBrainpoolp256PublicKeyY);
} // End of function f_verifyWithEcdsaBrainpoolp256WithSha256_1
/**
* @Desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The digest of the certificate issuer
* @param p_signature The signature
* @param p_ecdsaBrainpoolp384PublicKeyX The public key (x coordinate)
* @param p_ecdsaBrainpoolp384PublicKeyY The public key (y coordinate)
* @param p_compressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
function f_verifyWithEcdsaBrainpoolp384WithSha384(
in octetstring p_toBeVerifiedData,
in HashedId8 p_certificateIssuer,
in Oct48 p_ecdsaBrainpoolp384PublicKeyCompressed,
in integer p_compressedMode
) return boolean {
// log("f_verifyWithEcdsaBrainpoolp384WithSha384: toBeVerifiedData", p_toBeVerifiedData);
// log("f_verifyWithEcdsaBrainpoolp384WithSha384: toBeVerifiedData length", lengthof(p_toBeVerifiedData));
// log("f_verifyWithEcdsaBrainpoolp384WithSha384: signature", p_signature);
// log("f_verifyWithEcdsaBrainpoolp384WithSha384: ecdsaBrainpoolp384PublicKeyCompressed", p_ecdsaBrainpoolp384PublicKeyCompressed);
return fx_verifyWithEcdsaBrainpoolp384WithSha384(
p_toBeVerifiedData,
p_certificateIssuer,
p_signature,
p_ecdsaBrainpoolp384PublicKeyCompressed,
p_compressedMode
);
} // End of function f_verifyWithEcdsaBrainpoolp384WithSha384
/**
* @Desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The digest of the certificate issuer
* @param p_signature The signature
* @param p_ecdsaBrainpoolp384PublicKeyX The public key (x coordinate)
* @param p_ecdsaBrainpoolp384PublicKeyY The public key (y coordinate)
* @return true on success, false otherwise
*/
function f_verifyWithEcdsaBrainpoolp384WithSha384_1( // TODO To be removed
in octetstring p_toBeVerifiedData,
in HashedId8 p_certificateIssuer,
in octetstring p_signature,
in Oct48 p_ecdsaBrainpoolp384PublicKeyX,
in Oct48 p_ecdsaBrainpoolp384PublicKeyY
) return boolean {
// log("f_verifyWithEcdsaBrainpoolp384WithSha384: toBeVerifiedData", p_toBeVerifiedData);
// log("f_verifyWithEcdsaBrainpoolp384WithSha384: toBeVerifiedData length", lengthof(p_toBeVerifiedData));
// log("f_verifyWithEcdsaBrainpoolp384WithSha384: signature", p_signature);
// log("f_verifyWithEcdsaBrainpoolp384WithSha384: ecdsaBrainpoolp384PublicKeyX", p_ecdsaBrainpoolp384PublicKeyX);
// log("f_verifyWithEcdsaBrainpoolp384WithSha384: ecdsaBrainpoolp384PublicKeyY", p_ecdsaBrainpoolp384PublicKeyY);
return fx_verifyWithEcdsaBrainpoolp384WithSha384_1(
p_certificateIssuer,
p_signature,
p_ecdsaBrainpoolp384PublicKeyX,
p_ecdsaBrainpoolp384PublicKeyY);
} // End of function f_verifyWithEcdsaBrainpoolp384WithSha384_1
/**
* @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)
* @param p_publicKeyCompressed The compressed public keys
* @param p_compressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
out Oct32 p_privateKey,
out Oct32 p_publicKeyX,
out Oct32 p_publicKeyY,
out Oct32 p_publicKeyCompressed,
out integer p_compressedMode
return fx_generateKeyPair_nistp256(p_privateKey, p_publicKeyX, p_publicKeyY, p_publicKeyCompressed, p_compressedMode);
}
/**
* @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)
* @param p_publicKeyCompressed The compressed public keys
* @param p_compressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
function f_generate_key_pair_brainpoolp256(
out Oct32 p_privateKey,
out Oct32 p_publicKeyX,
out Oct32 p_publicKeyY,
out Oct32 p_publicKeyCompressed,
out integer p_compressedMode
return fx_generateKeyPair_brainpoolp256(p_privateKey, p_publicKeyX, p_publicKeyY, p_publicKeyCompressed, p_compressedMode);
}
/**
* @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)
* @param p_publicKeyCompressed The compressed public keys
* @param p_compressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
function f_generate_key_pair_brainpoolp384(
out Oct48 p_privateKey,
out Oct48 p_publicKeyX,
out Oct48 p_publicKeyY,
out Oct48 p_publicKeyCompressed,
out integer p_compressedMode
return fx_generateKeyPair_brainpoolp384(p_privateKey, p_publicKeyX, p_publicKeyY, p_publicKeyCompressed, p_compressedMode);
/**
* @desc Calculate digest over the certificate
* @param p_cert The certificate
* @return the HashedId8 value
* @see Draft ETSI TS 103 097 V1.1.14 Clause 4.2.13 HashedId8
*/
function f_calculateDigestFromCertificate(
in Certificate p_cert
) return HashedId8 {
var octetstring v_hash;
v_hash := f_calculateDigestSha384FromCertificate(p_cert);
}
return substr(v_hash, lengthof(v_hash) - 8, 8);
} // End of function f_calculateDigestFromCertificate
* @desc Calculate digest over the certificate
* @param p_cert The certificate
* @see Draft ETSI TS 103 097 V1.1.14 Clause 4.2.13 HashedId8
function f_calculateDigestSha256FromCertificate(
in EtsiTs103097Certificate p_cert
) return HashedId8 {
var octetstring v_toBeHashedData;
var octetstring v_hash;
v_toBeHashedData := bit2oct(encvalue(p_cert));
v_hash := f_hashWithSha256(v_toBeHashedData);
return substr(v_hash, lengthof(v_hash) - 8, 8);
} // End of function f_calculateDigestSha256FromCertificate
function f_calculateDigestSha384FromCertificate(
in EtsiTs103097Certificate p_cert
) return HashedId8 {
var octetstring v_toBeHashedData;
var octetstring v_hash;
v_toBeHashedData := bit2oct(encvalue(p_cert));
v_hash := f_hashWithSha384(v_toBeHashedData);
return substr(v_hash, lengthof(v_hash) - 8, 8);
} // End of function f_calculateDigestSha384FromCertificate
) return UInt16 {
if (ischosen(p_duration.seconds)) {
return p_duration.seconds;
} else if (ischosen(p_duration.minutes)) {
return p_duration.minutes;
} else if (ischosen(p_duration.hours)) {
return p_duration.hours;
} else if (ischosen(p_duration.sixtyHours)) {
return p_duration.sixtyHours;
} else if (ischosen(p_duration.years)) {
return p_duration.years;
/**
* @desc Initialize [out] certificates according to the specified certificate name
* @param p_certificateName The certificate name to be used
* @param p_aaCertificate The AA certificate [out]
* @param p_atCertificate The AT certificate [out]
* @return true on succes, false otherwise
* @see Draft ETSI TS 103 097 V1.1.14 Clause 4.2.13 HashedId8
function f_prepareCertificates(
in template (omit) charstring p_certificateName,
out EtsiTs103097Certificate p_aaCertificate,
out EtsiTs103097Certificate p_atCertificate
) runs on ItsSecurityBaseComponent return boolean {
// Load certificates if required
if (/*Spirent change*/lengthof(p_certificateName)>0 and (valueof(p_certificateName) != cc_taCert_A)) {
if (f_readCertificate(valueof(p_certificateName), p_atCertificate) == false){
if (f_readCertificate(oct2str(p_atCertificate.toBeSigned.cracaId), p_aaCertificate) == false) {
return false;
}
} else {
p_atCertificate := vc_atCertificate;
p_aaCertificate := vc_aaCertificate;
}
// Store the certificte to build this message
vc_lastAtCertificateUsed := p_atCertificate;
return true;
} // End of function f_prepareCertificates
* @desc This function build and sign the SecureMessage part covered by the signature process
* @param p_securedMessage The signed SecureMessage part
* @param p_payloadField Payloads to be included in the message
* @param p_mandatoryHeaders Mandatory headers for the selected profile
* @param p_headerInfo HeaderInfo to be inserted in the message
* @param p_securityProfile Selected security profile
* @return true on success, false otherwise
*/
function f_buildGnSecuredMessage(
out template (value) EtsiTs103097Data p_securedMessage,
in charstring p_certificateName,
in ToBeSignedData p_payloadField
) runs on ItsSecurityBaseComponent return boolean {
var octetstring v_secPayload, v_signature;
var Ieee1609Dot2Content v_toBeSignedPayload;
var HashedId8 v_certificateDigest;
var Oct32 v_privateKey;
// Prepare payload to be signed
v_secPayload := bit2oct(encvalue(v_toBeSignedData));
if (ispresent(p_certificateName) and (valueof(p_certificateName) != cc_taCert_A)) {
if(not f_readSigningKey(valueof(p_certificateName), v_privateKey)){
return false;
}
} else {
return false;
}
}
f_getCertificateDigest(p_certificateName, v_certificateDigest);
if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature)) {
v_signature := f_signWithEcdsaNistp256WithSha256(
v_secPayload,
v_certificateDigest,
v_privateKey
);
p_securedMessage.content.signedData.signature_ := m_signature_ecdsaNistP256(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(substr(v_signature, 0, 32)),
substr(v_signature, 32, 32)
)
);
} else if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP256r1Signature)) {
v_signature := f_signWithEcdsaBrainpoolp256WithSha256(
v_secPayload,
v_certificateDigest,
v_privateKey
);
p_securedMessage.content.signedData.signature_ := m_signature_ecdsaBrainpoolP256r1(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(substr(v_signature, 0, 32)),
substr(v_signature, 32, 32)
)
);
} // TODO To be continued
} // End of function f_buildGnSecuredMessage
/**
* @desc This function build and sign the SecureMessage part covered by the signature process including wrong elements of protocols. It is used for BO test cases
* @param p_securedMessage The signed SecureMessage part
* @param p_certificateName The certificate name
* @param p_protocolVersion The protocol version to be set. Default: 2
* @param p_trailerStatus The Traile behaviour:
* <li>0 for no trailer</li>
* <li>1 for invalid trailer</li>
* <li>2 for duplicated trailer</li>
* @param p_payloadField Payloads to be included in the message
* @param p_mandatoryHeaders Mandatory headers for the selected profile
* @param p_headerInfo HeaderInfo to be inserted in the message
* @param p_securityProfile Selected security profile
* @return true on success, false otherwise
*/
function f_buildGnSecuredMessage_Bo(
in template (value) charstring p_certificateName,
in integer p_trailerStatus := 0,
in template (value) HeaderInfo p_mandatoryHeaders,
in template (omit) HeaderInfo p_headerInfo := omit
// Local variables
var octetstring v_secPayload, v_signature;
var template (value) ToBeSignedData v_toBeSignedData;
var integer i, j, k, n;
var HeaderInfo v_headerFields := {};
var Ieee1609Dot2Content v_toBeSignedPayload;
var Oct32 v_privateKey;
var UInt8 v_trailerSize;
// Prepare headers
v_headerFields := valueof(p_mandatoryHeaders);
} else {/* FIXME To be reviewed
// Merge p_headerInfo and v_mandatoryHeaders into v_headerFields
j := 0; // index for v_mandatoryHeaders
k := 0; // index for v_headerFields
// Special processing for signer_info
if (lengthof(valueof(p_headerInfo)) > 0 and valueof(p_headerInfo[i].type_) == e_signer_info) {
v_headerFields[k] := valueof(p_headerInfo[i]);
k := k + 1;
i := i + 1;
}
for (j := j; j < lengthof(p_mandatoryHeaders); j := j + 1) {
// Search for mandatory header in p_HeaderFields
for (n := 0; n < lengthof(p_headerInfo); n := n + 1) {
if (valueof(p_headerInfo[n].type_) == valueof(p_mandatoryHeaders[j].type_)) {
// mandatory header already in p_HeaderFields
break;
}
} // End of 'for' statement
if (valueof(p_mandatoryHeaders[j].type_) != e_signer_info) {
// Add headers from p_headerInfo having lower number than mandatory header
for (n := i; n < lengthof(p_headerInfo) and valueof(p_headerInfo[n].type_) < valueof(p_mandatoryHeaders[j].type_); n := n + 1) {
v_headerFields[k] := valueof(p_headerInfo[n]);
k := k + 1;
i := i + 1;
}
}
// Add mandatory header
v_headerFields[k] := valueof(p_mandatoryHeaders[j]);
k := k + 1;
}
} // End of 'for' statement
// Add remaining headers from p_HeaderFields
for ( i := i; i < lengthof(p_headerInfo); i := i + 1) {
// Add headers from p_headerInfo having lower number than mandatory header
v_headerFields[k] := valueof(p_headerInfo[i]);
k := k + 1;
} // End of 'for' statement
// Prepare payload to be signed
/* FIXME To be reviewed v_toBeSignedPayload := valueof(p_payloadField);
if (p_trailerStatus == 0) {
v_trailerSize := 0;
} else if (p_trailerStatus == 1) {
v_trailerSize := 67;
} else if (p_trailerStatus == 2) {
v_trailerSize := 2 * 67;
} else {
v_trailerSize := 67;
}
v_toBeSignedData := m_toBeSignedSecuredMessage_wrong_protocol(
v_headerFields,
v_toBeSignedPayload,
e_signature,
p_protocolVersion,
v_trailerSize
);*/
// log("m_toBeSignedSecuredMessage_wrong_protocol=", v_toBeSignedData);
/* FIXME To be reviewedv_secPayload := bit2oct(encvalue(v_toBeSignedData));
// Signed payload
if (ispresent(p_certificateName) and (valueof(p_certificateName) != cc_taCert_A)) {
if(not f_readSigningKey(valueof(p_certificateName), v_privateKey)){
return false;
}
} else {
return false;
}
}
v_signature := f_signWithEcdsaNistp256WithSha256(
v_secPayload,
v_privateKey
/* FIXME To be reviewed if (p_trailerStatus == 0) { // No signature
p_payloadField,
{ }
);
v_trailerSize := 0;
} else if (p_trailerStatus == 2) { // Duplicate signature
p_payloadField,
{
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)
)
)
),
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)
)
)
)
}
);
} else if (p_trailerStatus == 3) { // Signature with reserved algorthm
p_securedMessage := m_ieee1609Dot2Data_wrong_protocol(
p_payloadField,
{
m_trailer_field_signature(
m_unknownSignature(
v_signature
)
)
}
);
} else { // Invalid signature
p_payloadField,
{
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)
)
)
)
}
);
p_securedMessage.trailer_fields[0].trailerField.signature_.ecdsaNistP256Signature.sSig := not4b(valueof(p_securedMessage.trailer_fields[0].trailerField.signature_.ecdsaNistP256Signature.sSig));
}*/
return false;/* FIXME To be reviewed true;*/
} // End of function f_buildGnSecuredMessage_Bo
* @desc This function build and sign the SecureMessage part covered by the signature process
* @param p_securedMessage The signed SecureMessage part
* @param p_payloadField Payloads to be included in the message
* @param p_signerIdentifierType Add digest or AT certificate or certificate chain
* @param p_certificateName The certificate identifier to be used. Default: TA_CERT_A
* @param p_addMissingHeaders Whether to add mandatory headers not present in p_headerInfo
* @see Draft ETSI TS 103 097 V1.1.14 Clause 7.1 Security profile for CAMs
out template (value) EtsiTs103097Data p_securedMessage,
in ToBeSignedData p_payloadField,
in SignerIdentifier p_signerIdentifierType,
in charstring p_certificateName := ""/*,
in boolean p_addMissingHeaders := true*/
) runs on ItsSecurityBaseComponent return boolean {
var EtsiTs103097Certificate v_aaCertificate, v_atCertificate;
if (f_prepareCertificates(p_certificateName, v_aaCertificate, v_atCertificate) == false) {
return false;
log("v_atCertificate = ", v_atCertificate);
// Fill sta structure with default values, these values will be updated later
p_securedMessage := m_etsiTs103097Data_signed(
m_signedData(
sha256,
p_payloadField,
m_signerIdentifier_self,
m_signature_ecdsaNistP256(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(int2oct(0, 32)),
int2oct(0, 32)
)
)
)
);
// Prepare mandatory headers
if (ischosen(p_signerIdentifierType.certificate)) { // Add the AT certificate
/* TODO
* v_signerInfo := valueof(
m_header_info_signer_info(
m_signerIdentifier_certificate(
v_atCertificate
)));
} else if (valueof(p_signerIdentifierType) == e_certificate_chain) { // Add the AT certificate + AA EtsiTs103097Certificate
v_signerInfo := valueof(
m_header_info_signer_info(
m_signerIdentifier_certificates(
{
v_aaCertificate,
}
)
));*/
} else if (ischosen(p_signerIdentifierType.digest)) { // Add the AT certificate digest
if (ischosen(v_atCertificate.issuer.sha256AndDigest)) {
p_securedMessage.content.signedData.hashId := sha256;
p_securedMessage.content.signedData.signer := m_signerIdentifier_digest(
f_calculateDigestSha256FromCertificate(v_atCertificate)
);
} else if (ischosen(v_atCertificate.issuer.sha384AndDigest)) {
p_securedMessage.content.signedData.hashId := sha384;
p_securedMessage.content.signedData.signer := m_signerIdentifier_digest(
f_calculateDigestSha384FromCertificate(v_atCertificate)
);
} else {
log("*** " & testcasename() & ": TODO ***");
stop;
}
if (ispresent(v_atCertificate.signature_)) {
if (ischosen(v_atCertificate.signature_.ecdsaBrainpoolP256r1Signature)) {
p_securedMessage.content.signedData.signature_ := m_signature_ecdsaBrainpoolP256r1(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(int2oct(0, 32)),
int2oct(0, 32)
)
);
} else if (ischosen(v_atCertificate.signature_.ecdsaBrainpoolP384r1Signature)) {
p_securedMessage.content.signedData.signature_ := m_signature_ecdsaBrainpoolP384r1(
m_ecdsaP384Signature(
m_eccP384CurvePoint_x_only(int2oct(0, 48)),
int2oct(0, 48)
)
);
} // else, m_signature_ecdsaNistP256 already chosen by default
}
log("p_securedMessage = ", p_securedMessage);
return f_buildGnSecuredMessage(p_securedMessage, p_certificateName, p_payloadField/*, v_mandatoryHeaders*/);
* @desc This function build and sign the SecureMessage part covered by the signature process including wrong elements of protocols. It is used for BO test cases
* @param p_securedMessage The signed SecureMessage part
* @param p_protocolVersion The protocol version to be set. Default: 2
* @param p_trailerStatus The Traile behaviour:
* <li>0 for no trailer</li>
* <li>1 for invalid trailer</li>
* <li>2 for duplicated trailer</li>
* @param p_payloadField Payloads to be included in the message
* @param p_signerIdentifierType Add digest or AT certificate or certificate chain
* @param p_headerInfo HeaderInfo to be inserted in the message
* @param p_certificateName The certificate identifier to be used. Default: TA_CERT_A
* @param p_addMissingHeaders Whether to add mandatory headers not present in p_headerInfo
* @param p_alterATCertificateSignature Set to true to alter the AT certificate signature
* @param p_alterAACertificateSignature Set to true to alter the AA certificate signature
*
* @see Draft ETSI TS 103 097 V1.1.14 Clause 7.1 Security profile for CAMs
function f_buildGnSecuredCam_Bo(
in integer p_trailerStatus := 0,
in ToBeSignedData p_payloadField,
in SignerIdentifier p_signerIdentifierType, // FIXME To be reviewed
in template (omit) HeaderInfo p_headerInfo := omit,
in boolean p_addMissingHeaders := true,
in boolean p_alterATCertificateSignature := false,
in boolean p_alterAACertificateSignature := false
) runs on ItsSecurityBaseComponent return boolean {
// Local variables
var EtsiTs103097Certificate v_aaCertificate, v_atCertificate;
var HeaderInfo v_mandatoryHeaders := {};
var HeaderInfo v_signerInfo;
// Load certificates if required
if (f_prepareCertificates(p_certificateName, v_aaCertificate, v_atCertificate) == false) {
return false;
}
v_atCertificate.signature_.ecdsaNistP256Signature.sSig := not4b(v_atCertificate.signature_.ecdsaNistP256Signature.sSig);
v_aaCertificate.signature_.ecdsaNistP256Signature.sSig := not4b(v_aaCertificate.signature_.ecdsaNistP256Signature.sSig);
/* FIXME To be reviewed if (p_addMissingHeaders == true) {
// Prepare mandatory headers
if (valueof(p_signerIdentifierType) == e_certificate) { // Add the AT certificate
v_signerInfo := valueof(
m_header_info_signer_info(
m_signerIdentifier_certificate(
v_atCertificate
)));
} else if (valueof(p_signerIdentifierType) == e_certificate_chain) { // Add the AT certificate + AA EtsiTs103097Certificate
v_signerInfo := valueof(
m_header_info_signer_info(
m_signerIdentifier_certificates(
{
v_aaCertificate,
v_atCertificate
}
)
));
} else if (valueof(p_signerIdentifierType) == e_certificate_digest_with_sha256) { // Add the AT certificate digest
v_signerInfo := valueof(
m_header_info_signer_info(
m_issuerIdentifier_sha256AndDigest(
f_calculateDigestFromCertificate(v_atCertificate)
)));
}
v_mandatoryHeaders := {
v_signerInfo,
valueof(m_header_info_generation_time(1000 * f_getCurrentTime())), // In us
valueof(m_header_info_its_aid(c_its_aid_CAM))
return f_buildGnSecuredMessage_Bo(p_securedMessage, p_certificateName, p_protocolVersion, p_trailerStatus, p_payloadField, v_mandatoryHeaders, p_headerInfo);
} // End of function f_buildGnSecuredCam_Bo
/**
* @desc This function build and sign the SecureMessage part covered by the signature process
* @param p_securedMessage The signed SecureMessage part
* @param p_payloadField Payloads to be included in the message
* @param p_signerIdentifierType Add digest or AT certificate or certificate chain
* @param p_threeDLocation The 3D location
* @param p_headerInfo HeaderInfo to be inserted in the message
* @param p_certificateName The certificate identifier to be used. Default: TA_CERT_A
* @param p_addMissingHeaders Whether to add mandatory headers not present in p_headerInfo
* @return true on success, false otherwise
*/
out template (value) EtsiTs103097Data p_securedMessage,
in ToBeSignedData p_payloadField,
in SignerIdentifier p_signerIdentifierType,
in template (omit) HeaderInfo p_headerInfo := omit,
) runs on ItsSecurityBaseComponent return boolean {
var EtsiTs103097Certificate v_aaCertificate, v_atCertificate;
var HeaderInfo v_mandatoryHeaders := {};
var HeaderInfo v_signerInfo;
if (f_prepareCertificates(p_certificateName, v_aaCertificate, v_atCertificate) == false) {
return false;
/* FIXME To be reviewed if (p_addMissingHeaders == true) {
if (valueof(p_signerIdentifierType) == e_certificate) { // Add the AT certificate
v_signerInfo := valueof(
m_header_info_signer_info(
m_signerIdentifier_certificate(
v_atCertificate
)));
} else if (valueof(p_signerIdentifierType) == e_certificate_chain) { // Add the AT certificate + AA EtsiTs103097Certificate
v_signerInfo := valueof(
m_header_info_signer_info(
m_signerIdentifier_certificates(
{
v_aaCertificate,
v_atCertificate
}
)
} else if (valueof(p_signerIdentifierType) == e_certificate_digest_with_sha256) { // Add the AT certificate digest
v_signerInfo := valueof(
m_header_info_signer_info(
m_issuerIdentifier_sha256AndDigest(
v_atCertificate.cracaId
valueof(m_header_info_generation_time(1000 * f_getCurrentTime())), // In us
valueof(m_header_info_generation_location(p_threeDLocation)),
valueof(m_header_info_its_aid(c_its_aid_DENM))
// Build the secured message and return it
return f_buildGnSecuredMessage(p_securedMessage, p_certificateName, p_payloadField/*, v_mandatoryHeaders*/);
/**
* @desc This function build and sign the SecureMessage part covered by the signature process including wrong elements of protocols. It is used for BO test cases
* @param p_securedMessage The signed SecureMessage part
* @param p_protocolVersion The protocol version to be set. Default: 2
* @param p_trailerStatus The Traile behaviour:
* <li>0 for no trailer</li>
* <li>1 for invalid trailer</li>
* <li>2 for duplicated trailer</li>
* @param p_payloadField Payloads to be included in the message
* @param p_signerIdentifierType Add digest or AT certificate or certificate chain
* @param p_threeDLocation The 3D location
* @param p_headerInfo HeaderInfo to be inserted in the message
* @param p_certificateName The certificate identifier to be used. Default: TA_CERT_A
* @param p_addMissingHeaders Whether to add mandatory headers not present in p_headerInfo
* @return true on success, false otherwise
*/
function f_buildGnSecuredDenm_Bo(
in integer p_trailerStatus := 0,
in ToBeSignedData p_payloadField,
in SignerIdentifier p_signerIdentifierType, // FIXME To be reviewed
in ThreeDLocation p_threeDLocation,
in template (omit) HeaderInfo p_headerInfo := omit,
in boolean p_addMissingHeaders := true
) runs on ItsSecurityBaseComponent return boolean {
// Local variables
var EtsiTs103097Certificate v_aaCertificate, v_atCertificate;
var HeaderInfo v_mandatoryHeaders := {};
var HeaderInfo v_signerInfo;
// Load certificates if required
if (f_prepareCertificates(p_certificateName, v_aaCertificate, v_atCertificate) == false) {
return false;
}
// Add additional headers if required
/* FIXME To be reviewed if (p_addMissingHeaders == true) {
// Prepare mandatory headers
if (valueof(p_signerIdentifierType) == e_certificate) { // Add the AT certificate
v_signerInfo := valueof(
m_header_info_signer_info(
m_signerIdentifier_certificate(
v_atCertificate
)));
} else if (valueof(p_signerIdentifierType) == e_certificate_chain) { // Add the AT certificate + AA EtsiTs103097Certificate
v_signerInfo := valueof(
m_header_info_signer_info(
m_signerIdentifier_certificates(
{
v_aaCertificate,
v_atCertificate
}
)
));
} else if (valueof(p_signerIdentifierType) == e_certificate_digest_with_sha256) { // Add the AT certificate digest
v_signerInfo := valueof(
m_header_info_signer_info(
m_issuerIdentifier_sha256AndDigest(
v_atCertificate.cracaId
)));
}
v_mandatoryHeaders := {
v_signerInfo,
valueof(m_header_info_generation_time(1000 * f_getCurrentTime())), // In us
valueof(m_header_info_generation_location(p_threeDLocation)),
valueof(m_header_info_its_aid(c_its_aid_DENM))
// Build the secured message and return it
return f_buildGnSecuredMessage_Bo(p_securedMessage, p_certificateName, p_protocolVersion, p_trailerStatus, p_payloadField, v_mandatoryHeaders, p_headerInfo);
} // End of function f_buildGnSecuredDenm_Bo
* @desc This function build and sign the SecureMessage part covered by the signature process
* @param p_securedMessage The signed SecureMessage part
* @param p_payloadField Payloads to be included in the message
* @param p_signerIdentifierType Add digest or AT certificate or certificate chain
* @param p_headerInfo HeaderInfo to be inserted in the message
* @param p_certificateName The certificate identifier to be used. Default: TA_CERT_A
* @param p_addMissingHeaders Whether to add mandatory headers not present in p_headerInfo
* @return true on success, false otherwise
*/
function f_buildGnSecuredOtherMessage(
out template (value) EtsiTs103097Data p_securedMessage,
in ToBeSignedData p_payloadField,
in SignerIdentifier p_signerIdentifierType, // FIXME To be reviewed
in template (omit) HeaderInfo p_headerInfo := omit,
) runs on ItsSecurityBaseComponent return boolean {
var EtsiTs103097Certificate v_aaCertificate, v_atCertificate;
var HeaderInfo v_mandatoryHeaders := {};
var HeaderInfo v_signerInfo;
if (f_prepareCertificates(p_certificateName, v_aaCertificate, v_atCertificate) == false) {
return false;
/* FIXME To be reviewed if (p_addMissingHeaders == true) {
if (valueof(p_signerIdentifierType) == e_certificate) { // Add the AT certificate
v_signerInfo := valueof(
m_header_info_signer_info(
m_signerIdentifier_certificate(
v_atCertificate
)));
} else if (valueof(p_signerIdentifierType) == e_certificate_chain) { // Add the AT certificate + AA EtsiTs103097Certificate
v_signerInfo := valueof(
m_header_info_signer_info(
m_signerIdentifier_certificates(
{
v_aaCertificate,
v_atCertificate
}
)
} else if (valueof(p_signerIdentifierType) == e_certificate_digest_with_sha256) { // Add the AT certificate digest
v_signerInfo := valueof(
m_header_info_signer_info(
m_issuerIdentifier_sha256AndDigest(
v_atCertificate.cracaId
valueof(m_header_info_generation_time(1000 * f_getCurrentTime())), // In us
valueof(m_header_info_generation_location(p_threeDLocation))
// Build the secured message and return it
return f_buildGnSecuredMessage(p_securedMessage, p_certificateName, p_payloadField/*, v_mandatoryHeaders*/);
} // End of function f_buildGnSecuredOtherMessage
/**
* @desc This function build and sign the SecureMessage part covered by the signature process including wrong elements of protocols. It is used for BO test cases
* @param p_securedMessage The signed SecureMessage part
* @param p_protocolVersion The protocol version to be set. Default: 2
* @param p_trailerStatus The Traile behaviour:
* <li>0 for no trailer</li>
* <li>1 for invalid trailer</li>
* <li>2 for duplicated trailer</li>
* @param p_payloadField Payloads to be included in the message
* @param p_signerIdentifierType Add digest or AT certificate or certificate chain
* @param p_headerInfo HeaderInfo to be inserted in the message
* @param p_certificateName The certificate identifier to be used. Default: TA_CERT_A
* @param p_addMissingHeaders Whether to add mandatory headers not present in p_headerInfo
* @return true on success, false otherwise
*/
function f_buildGnSecuredOtherMessage_Bo(
in ToBeSignedData p_payloadField,
in SignerIdentifier p_signerIdentifierType, // FIXME To be reviewed
in template (omit) HeaderInfo p_headerInfo := omit,
in boolean p_addMissingHeaders := true
) runs on ItsSecurityBaseComponent return boolean {
// Local variables
var EtsiTs103097Certificate v_aaCertificate, v_atCertificate;
var HeaderInfo v_mandatoryHeaders := {};
var HeaderInfo v_signerInfo;
// Load certificates if required
if (f_prepareCertificates(p_certificateName, v_aaCertificate, v_atCertificate) == false) {
return false;
}
// Add additional headers if required
/* FIXME To be reviewed if (p_addMissingHeaders == true) {
if (valueof(p_signerIdentifierType) == e_certificate) { // Add the AT certificate
m_header_info_signer_info(
m_signerIdentifier_certificate(
} else if (valueof(p_signerIdentifierType) == e_certificate_chain) { // Add the AT certificate + AA EtsiTs103097Certificate
m_header_info_signer_info(
m_signerIdentifier_certificates(
{
v_aaCertificate,
v_atCertificate
}
)
));
} else if (valueof(p_signerIdentifierType) == e_certificate_digest_with_sha256) { // Add the AT certificate digest
m_header_info_signer_info(
m_issuerIdentifier_sha256AndDigest(
v_atCertificate.cracaId
)));
}
v_mandatoryHeaders := {
v_signerInfo,
valueof(m_header_info_generation_time(1000 * f_getCurrentTime())), // In us
valueof(m_header_info_generation_location(p_threeDLocation))
// FIXME To be done
// Build the secured message and return it
return f_buildGnSecuredMessage(p_securedMessage, p_certificateName, p_payloadField/*, v_mandatoryHeaders*/);
} // End of function f_buildGnSecuredOtherMessage_Bo
} // End of group hostSignatureHelpers
group deviceSignatureHelpers {
/**
* @desc Retrieve the HashedId8 to be sent to the IUT, based on the provided certificate identifier
* @param p_certificateName The certificate the IUT shall use
* @return The HashedId8 to be sent to the IUT in the UtInitialize command
* @verdict Unchanged
* @remark Component variable vc_hashedId8ToBeUsed shall be set with the IUT certificate to be used
*/
function f_setupIutCertificate(
in charstring p_certificateName
) runs on ItsSecurityBaseComponent return HashedId8 {
// Local variables
// var EtsiTs103097Certificate v_atCertificate;
var HashedId8 v_hashedId8 := '0000000000000000'O;
// Sanity check
if (lengthof(p_certificateName) == 0) {
return v_hashedId8;
}
// Load certificates
if(f_getCertificateDigest(p_certificateName, v_hashedId8) == false) {
v_hashedId8 := '0000000000000000'O;
}
return v_hashedId8;
} // End of function f_setupIutCertificate
* @desc Verify the signature of the provided certificate
* @param p_certificateToBeVerified EtsiTs103097Certificate to be verified
* @param p_publicKey Public key to verify the certificate signature
* @return true on success, false otherwise
* @verdict
*/
function f_verifyCertificateSignatureWithPublicKey(
in template (value) EtsiTs103097Certificate p_certificateToBeVerified,
in template (value) PublicVerificationKey p_publicVerificationKey
var ToBeSignedCertificate v_toBeSignedCertificate;
var octetstring v_enc_msg;
var octetstring v_signature;
log("f_verifyCertificateSignatureWithPublicKey: p_publicVerificationKey=", p_publicVerificationKey);
// Create ToBeSignedCertificate payload to be signed
v_toBeSignedCertificate := valueof(p_certificateToBeVerified.toBeSigned);
log("f_verifyCertificateSignatureWithPublicKey: v_toBeSignedCertificate=", v_toBeSignedCertificate);
v_enc_msg := bit2oct(encvalue(v_toBeSignedCertificate));
log("f_verifyCertificateSignatureWithPublicKey: v_enc_msg=", v_enc_msg);
// Verify payload
if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP256r1)) {
v_signature := valueof(p_certificateToBeVerified.signature_.ecdsaBrainpoolP256r1Signature.rSig.x_only) & valueof(p_certificateToBeVerified.signature_.ecdsaBrainpoolP256r1Signature.sSig);
log("f_verifyCertificateSignatureWithPublicKey: v_signedData=", v_signature);
if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP256r1.uncompressedP256)) {
return f_verifyWithEcdsaBrainpoolp256WithSha256_1(
v_enc_msg,
valueof(p_certificateToBeVerified.issuer.sha256AndDigest),
v_signature,
valueof(p_publicVerificationKey.ecdsaBrainpoolP256r1.uncompressedP256.x),
valueof(p_publicVerificationKey.ecdsaBrainpoolP256r1.uncompressedP256.y)
);
} else if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP256r1.compressed_y_0)) {
return f_verifyWithEcdsaBrainpoolp256WithSha256(
v_enc_msg,
valueof(p_certificateToBeVerified.issuer.sha256AndDigest),
v_signature,
valueof(p_publicVerificationKey.ecdsaBrainpoolP256r1.compressed_y_0),
0 // Latest bit of the Y-coordinate is 0
);
} else if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP256r1.compressed_y_1)) {
return f_verifyWithEcdsaBrainpoolp256WithSha256(
v_enc_msg,
valueof(p_certificateToBeVerified.issuer.sha256AndDigest),
v_signature,
valueof(p_publicVerificationKey.ecdsaBrainpoolP256r1.compressed_y_1),
1 // Latest bit of the Y-coordinate is 1
);
} else {
log("f_verifyCertificateSignatureWithPublicKey: Unknown PublicVerificationKey value");
return false;
} else if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP384r1)) {
v_signature := valueof(p_certificateToBeVerified.signature_.ecdsaBrainpoolP384r1Signature.rSig.x_only) & valueof(p_certificateToBeVerified.signature_.ecdsaBrainpoolP384r1Signature.sSig);
log("f_verifyCertificateSignatureWithPublicKey: v_signedData=", v_signature);
if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP384r1.uncompressedP384)) {
return f_verifyWithEcdsaBrainpoolp384WithSha384_1(
v_enc_msg,
valueof(p_certificateToBeVerified.issuer.sha384AndDigest),
v_signature,
valueof(p_publicVerificationKey.ecdsaBrainpoolP384r1.uncompressedP384.x),
valueof(p_publicVerificationKey.ecdsaBrainpoolP384r1.uncompressedP384.y)
);
} else if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP384r1.compressed_y_0)) {
return f_verifyWithEcdsaBrainpoolp384WithSha384(
v_enc_msg,
valueof(p_certificateToBeVerified.issuer.sha384AndDigest),
v_signature,
valueof(p_publicVerificationKey.ecdsaBrainpoolP384r1.compressed_y_0),
0 // Latest bit of the Y-coordinate is 0
);
} else if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP384r1.compressed_y_1)) {
return f_verifyWithEcdsaBrainpoolp384WithSha384(
v_enc_msg,
valueof(p_certificateToBeVerified.issuer.sha384AndDigest),
v_signature,
valueof(p_publicVerificationKey.ecdsaBrainpoolP384r1.compressed_y_1),
1 // Latest bit of the Y-coordinate is 1
);
} else {
log("f_verifyCertificateSignatureWithPublicKey: Unknown PublicVerificationKey value");
return false;
} else if (ischosen(p_publicVerificationKey.ecdsaNistP256)) {
v_signature := valueof(p_certificateToBeVerified.signature_.ecdsaNistP256Signature.rSig.x_only) & valueof(p_certificateToBeVerified.signature_.ecdsaNistP256Signature.sSig);
log("f_verifyCertificateSignatureWithPublicKey: v_signedData=", v_signature);
if (ischosen(p_publicVerificationKey.ecdsaNistP256.uncompressedP256)) {
return f_verifyWithEcdsaNistp256WithSha256_1(
v_enc_msg,
valueof(p_certificateToBeVerified.issuer.sha256AndDigest),
v_signature,
valueof(p_publicVerificationKey.ecdsaNistP256.uncompressedP256.x),
valueof(p_publicVerificationKey.ecdsaNistP256.uncompressedP256.y)
);
} else if (ischosen(p_publicVerificationKey.ecdsaNistP256.compressed_y_0)) {
return f_verifyWithEcdsaNistp256WithSha256(
v_enc_msg,
valueof(p_certificateToBeVerified.issuer.sha256AndDigest),
v_signature,
valueof(p_publicVerificationKey.ecdsaNistP256.compressed_y_0),
0 // Latest bit of the Y-coordinate is 0
);
} else if (ischosen(p_publicVerificationKey.ecdsaNistP256.compressed_y_1)) {
return f_verifyWithEcdsaNistp256WithSha256(
v_enc_msg,
valueof(p_certificateToBeVerified.issuer.sha256AndDigest),
v_signature,
valueof(p_publicVerificationKey.ecdsaNistP256.compressed_y_1),
1 // Latest bit of the Y-coordinate is 1
);
} else {
log("f_verifyCertificateSignatureWithPublicKey: Unknown PublicVerificationKey value");
return false;
} // End of finction f_verifyCertificateSignatureWithPublicKey
* @desc Verify the signature of the provided secured message
* @param p_certificateToBeVerified EtsiTs103097Certificate to be verified
* @param p_issuingCertificate Issuing certificate
* @return true on success, false otherwise
* @verdict
*/
function f_verifyCertificateSignatureWithIssuingCertificate(
in template (value) EtsiTs103097Certificate p_certificateToBeVerified,
in template (value) EtsiTs103097Certificate p_issuingCertificate
// Sanity checks
if (not(ischosen(p_issuingCertificate.toBeSigned.verifyKeyIndicator.verificationKey))) {
return false;
}
return f_verifyCertificateSignatureWithPublicKey(
p_certificateToBeVerified,
p_issuingCertificate.toBeSigned.verifyKeyIndicator.verificationKey
);
} // End of function f_verifyCertificateSignatureWithIssuingCertificate
* @desc Verify the signature of the provided secured message for ECDSA Nist-P256 algorithm
* @param p_securedMessage The message to be verified
* @param p_publicKey The ECDSA public key to verify a signature
* @param p_certificate EtsiTs103097Certificate to be used to verify the message
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_verifyGnSecuredMessageSignature_ecdsaNistP256(
in template (value) Ieee1609Dot2Data p_securedMessage,
in template (value) HashedId8 p_certificateIssuer,
in template (value) EccP256CurvePoint p_publicKey
) return boolean {
// Local variables
var octetstring v_secPayload;
var octetstring v_signedData;
var boolean v_result := false;
var template (value) ToBeSignedData v_toBeSignedData;
log(">>> f_verifyGnSecuredMessageSignature_ecdsaNistP256: p_securedMessage= ", p_securedMessage);
log(">>> f_verifyGnSecuredMessageSignature_ecdsaNistP256: p_certificateIssuer= ", p_certificateIssuer);
log(">>> f_verifyGnSecuredMessageSignature_ecdsaNistP256: p_publicKey= ", p_publicKey);
// Create Ieee1609Dot2Data payload to be signed
v_toBeSignedData := valueof(p_securedMessage.content.signedData.tbsData);
log("f_verifyGnSecuredMessageSignature_ecdsaNistP256: v_toBeSignedData=", p_securedMessage.content.signedData.tbsData);
v_secPayload := bit2oct(encvalue(v_toBeSignedData));
log("f_verifyGnSecuredMessageSignature_ecdsaNistP256: v_secPayload=", v_secPayload);
// Verify payload
v_signedData := valueof(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature.rSig.x_only) & valueof(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature.sSig);
log("f_verifyGnSecuredMessageSignature_ecdsaNistP256: v_signedData=", v_signedData);
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
if (ischosen(p_publicKey.uncompressedP256)) {
v_result := f_verifyWithEcdsaNistp256WithSha256_1(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.uncompressedP256.x),
valueof(p_publicKey.uncompressedP256.y)
);
} else if (ischosen(p_publicKey.compressed_y_0)) {
v_result := f_verifyWithEcdsaNistp256WithSha256(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.compressed_y_0),
0
);
} else if (ischosen(p_publicKey.compressed_y_1)) {
v_result := f_verifyWithEcdsaNistp256WithSha256(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.compressed_y_1),
1
);
}
log("f_verifyGnSecuredMessageSignature_ecdsaNistP256: v_result=", v_result);
return v_result;
} // End of function f_verifyGnSecuredMessageSignature_ecdsaNistP256
/**
* @desc Verify the signature of the provided secured message for ECDSA Brainpool-P256 algorithm
* @param p_securedMessage The message to be verified
* @param p_publicKey The ECDSA public key to verify a signature
* @param p_certificate EtsiTs103097Certificate to be used to verify the message
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1(
in template (value) Ieee1609Dot2Data p_securedMessage,
in template (value) HashedId8 p_certificateIssuer,
in template (value) EccP256CurvePoint p_publicKey
) return boolean {
// Local variables
var octetstring v_secPayload;
var octetstring v_signedData;
var boolean v_result := false;
var template (value) ToBeSignedData v_toBeSignedData;
log(">>> f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1: p_securedMessage= ", p_securedMessage);
log(">>> f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1: p_certificateIssuer= ", p_certificateIssuer);
log(">>> f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1: p_publicKey= ", p_publicKey);
// Create Ieee1609Dot2Data payload to be signed
v_toBeSignedData := valueof(p_securedMessage.content.signedData.tbsData);
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1: v_toBeSignedData=", p_securedMessage.content.signedData.tbsData);
v_secPayload := bit2oct(encvalue(v_toBeSignedData));
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1: v_secPayload=", v_secPayload);
// Verify payload
v_signedData := valueof(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.rSig.x_only) & valueof(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.sSig);
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1: v_signedData=", v_signedData);
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
if (ischosen(p_publicKey.uncompressedP256)) {
v_result := f_verifyWithEcdsaBrainpoolp256WithSha256_1(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.uncompressedP256.x),
valueof(p_publicKey.uncompressedP256.y)
);
} else if (ischosen(p_publicKey.compressed_y_0)) {
v_result := f_verifyWithEcdsaBrainpoolp256WithSha256(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.compressed_y_0),
0
);
} else if (ischosen(p_publicKey.compressed_y_1)) {
v_result := f_verifyWithEcdsaBrainpoolp256WithSha256(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.compressed_y_1),
1
);
}
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1: v_result=", v_result);
return v_result;
} // End of function f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1
/**
* @desc Verify the signature of the provided secured message for ECDSA Brainpool-P384 algorithm
* @param p_securedMessage The message to be verified
* @param p_publicKey The ECDSA public key to verify a signature
* @param p_certificate EtsiTs103097Certificate to be used to verify the message
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1(
in template (value) Ieee1609Dot2Data p_securedMessage,
in template (value) HashedId8 p_certificateIssuer,
in template (value) EccP384CurvePoint p_publicKey
) return boolean {
// Local variables
var octetstring v_secPayload;
var octetstring v_signedData;
var boolean v_result := false;
var template (value) ToBeSignedData v_toBeSignedData;
log(">>> f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1: p_securedMessage= ", p_securedMessage);
log(">>> f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1: p_certificateIssuer= ", p_certificateIssuer);
log(">>> f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1: p_publicKey= ", p_publicKey);
// Create Ieee1609Dot2Data payload to be signed
v_toBeSignedData := valueof(p_securedMessage.content.signedData.tbsData);
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1: v_toBeSignedData=", p_securedMessage.content.signedData.tbsData);
v_secPayload := bit2oct(encvalue(v_toBeSignedData));
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1: v_secPayload=", v_secPayload);
v_signedData := valueof(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP384r1Signature.rSig.x_only) & valueof(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP384r1Signature.sSig);
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1: v_signedData=", v_signedData);
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
if (ischosen(p_publicKey.uncompressedP384)) {
v_result := f_verifyWithEcdsaBrainpoolp384WithSha384_1(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.uncompressedP384.x),
valueof(p_publicKey.uncompressedP384.y)
);
} else if (ischosen(p_publicKey.compressed_y_0)) {
v_result := f_verifyWithEcdsaBrainpoolp384WithSha384(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.compressed_y_0),
0
);
} else if (ischosen(p_publicKey.compressed_y_1)) {
v_result := f_verifyWithEcdsaBrainpoolp384WithSha384(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.compressed_y_1),
1
);
}
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1: v_result=", v_result);
} // End of function f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1
* @desc Verify the signature of the provided secured message
* @param p_securedMessage
* @param p_certificate EtsiTs103097Certificate to be used to verify the message
* @return true on success, false otherwise
* @verdict
*/
function f_verifyGnSecuredMessageSignatureWithCertificate(
in template (value) Ieee1609Dot2Data p_securedMessage,
in template (value) EtsiTs103097Certificate p_certificate
if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP256r1Signature)) {
return f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1(p_securedMessage, p_certificate.issuer.sha256AndDigest, p_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1);
} else if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP384r1Signature)) {
return f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1(p_securedMessage, p_certificate.issuer.sha384AndDigest, p_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1);
} else if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature)) {
return f_verifyGnSecuredMessageSignature_ecdsaNistP256(p_securedMessage, p_certificate.issuer.sha256AndDigest, p_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256);
} // End of function f_verifyGnSecuredOtherMessageWithDeviceCertificate
} // End of group deviceSignatureHelpers
garciay
committed
* @desc return Ieee1609Dot2Data header field of given type or null if none
* @param p_msg the Ieee1609Dot2Data
* @return HeaderInfo of given type if any or null
in template(omit) Ieee1609Dot2Data p_securedMessage,
out HeaderInfo p_return
) return boolean {
if (not isvalue(p_securedMessage)) {
testcase.stop(__SCOPE__ & " can not handle omitted secured message values");
}
v_securedMessage := valueof(p_securedMessage);
if (ispresent(v_securedMessage.content.signedData)) {
p_return := v_securedMessage.content.signedData.tbsData.headerInfo;
return true;
}
}
/**
* @desc return SignerIdentifier Ieee1609Dot2Data field
in template(omit) Ieee1609Dot2Data p_securedMessage,
out SignerIdentifier p_signerIdentifier
) return boolean {
if (not isvalue(p_securedMessage)) {
testcase.stop(__SCOPE__ & " can not handle omitted secured message values");
}
if (ischosen(p_securedMessage.content.signedData)) {
p_signerIdentifier := valueof(p_securedMessage.content.signedData.signer);
return true;
}
log("f_getMsgSignerIdentifier: return false");
* @desc Set the generation location as defined in Draft ETSI TS 103 097 V1.1.14 Clause 7.2 Security profile for DENMs
* @param p_latitude The latitude value of the ITS-S position
* @param p_longitude The longitude value of the ITS-S position
* @param p_elevation The elevation value of the ITS-S position
* @verdict Unchanged
*/
function f_setGenerationLocation(
in SecLatitude p_latitude,
in SecLongitude p_longitude,
in SecElevation p_elevation := 0
) 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 {
// Setup certificates memory cache
if (fx_loadCertificates(PX_CERTIFICATE_POOL_PATH, p_configId) == true) {
// Setup security component variables
if (f_readCertificate(cc_taCert_A, vc_atCertificate) == true) {
var HashedId8 v_issuer;
log("Issuer: ", vc_atCertificate.issuer);
if (ischosen(vc_atCertificate.issuer.sha256AndDigest)) {
v_issuer := vc_atCertificate.issuer.sha256AndDigest;
} else if (ischosen(vc_atCertificate.issuer.sha384AndDigest)) {
v_issuer := vc_atCertificate.issuer.sha384AndDigest;
} else {
log("AT certificate cannot be issued by CA");
return false;
}
log("Selected issuer: ", v_issuer);
if (f_getCertificateFromDigest(v_issuer, vc_aaCertificate)) {
if (f_readSigningKey(cc_taCert_A, vc_signingPrivateKey) == true) {
f_readEncryptingKey(cc_taCert_A, vc_encryptPrivateKey);
return true;
}
log("f_loadCertificates: Failed to load signing key for ", cc_taCert_A);
} else {
log("f_loadCertificates: Failed to load AA certificate for ", cc_taCert_A);
}
} else {
log("f_loadCertificates: Failed to load AT certificate for ", cc_taCert_A);
}
log("f_loadCertificates: Failed to load certificates from ", PX_CERTIFICATE_POOL_PATH);
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 := ''O;
vc_encryptPrivateKey := ''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
*/
) runs on ItsSecurityBaseComponent return boolean {
var octetstring v_certificate;
if (fx_readCertificate(p_certificateId, v_certificate) == true) {
var bitstring v_oct2bit;
var integer v_result;
v_oct2bit := oct2bit(v_certificate);
v_result := decvalue(v_oct2bit, p_certificate);
if (v_result == 0) {
return true;
}
}
log("f_readCertificate: Failed to retrieve ", p_certificateId);
} // End of function f_readCertificate
/**
* @desc Read the specified certificate
* @param p_certificateId the certificate identifier
* @param p_certificate the expected certificate
* @return true on success, false otherwise
*/
function f_getCertificateDigest(
in charstring p_certificateId,
out HashedId8 p_digest
) runs on ItsSecurityBaseComponent return boolean {
if (not fx_readCertificateDigest(p_certificateId, p_digest)){
log("f_getCertificateDigest: Failed to retrieve digest for ", p_certificateId);
return false;
}
return true;
} // End of function f_getCertificateDigest
function f_getCertificateFromDigest(
in HashedId8 p_digest,
out EtsiTs103097Certificate p_certificate
) runs on ItsSecurityBaseComponent return boolean {
var charstring v_certificate_id;
if (not(fx_readCertificateFromDigest(p_digest, v_certificate_id))) {
log("f_getCertificateFromDigest: Failed to retrieve digest for ", p_digest);
return false;
}
if (not(f_readCertificate(v_certificate_id, p_certificate))) {
log("f_getCertificateFromDigest: Failed to retrieve digest for ", v_certificate_id);
return false;
}
return true;
} // End of function f_getCertificateFromDigest
* @desc Read the signing private key for the specified certificate
* @param p_keysId the keys identifier
* @param p_signingPrivateKey the signing private key
* @return true on success, false otherwise
*/
function f_readSigningKey(
in charstring p_keysId,
out Oct32 p_signingPrivateKey
) runs on ItsSecurityBaseComponent return boolean {
return fx_readSigningKey(p_keysId, p_signingPrivateKey);
} // End of function f_readSigningKey
/**
* @desc Read the encrypting private keys for the specified certificate
* @param p_keysId the keys identifier
* @param p_encryptPrivateKey the encrypt private key
* @return true on success, false otherwise
*/
function f_readEncryptingKey(
) runs on ItsSecurityBaseComponent return boolean {
return fx_readEncryptingKey(p_keysId, p_encryptPrivateKey);
} // End of function f_readEncryptingKey
function f_getCertificateValidityRestriction(
in template (value) EtsiTs103097Certificate p_cert,
out template (value) ValidityPeriod p_validityPeriod,
out template (omit) GeographicRegion p_geographicRegion
) return boolean {
p_validityPeriod := valueof(p_cert.toBeSigned.validityPeriod);
if (ispresent(p_cert.toBeSigned.region)) {
p_geographicRegion := valueof(p_cert.toBeSigned.region);
} else {
p_geographicRegion := omit;
}
} // End of function f_getCertificateValidityRestriction
group certificatesCaching {
function f_createCertificatesCaching(
out CertificatesCaching p_certificatesCaching
) return boolean {
p_certificatesCaching := { };
for (var integer v_counter := 0; v_counter < lengthof(p_certificates); v_counter := v_counter + 1) {
var CertificatesCachingItem v_item;
v_item.certificate := p_certificates[v_counter];
v_item.hashedId8 := f_calculateDigestSha256FromCertificate(v_item.certificate);
p_certificatesCaching[v_counter] := v_item;
} // End of 'for' statement
return true;
}
function f_getCertificateFromCaching(
in CertificatesCaching p_certificatesCaching,
in HashedId8 p_hashedId8,
) return boolean {
for (var integer v_counter := 0; v_counter < lengthof(p_certificatesCaching); v_counter := v_counter + 1) {
if (match(p_certificatesCaching[v_counter].hashedId8, p_hashedId8) == true) {
p_certificate := p_certificatesCaching[v_counter].certificate;
return true;
}
} // End of 'for' statement
return false;
}
function f_getCertificatesCachingItem(
in CertificatesCaching p_certificatesCaching,
in UInt8 p_index,
) return boolean {
if (lengthof(p_certificatesCaching) < p_index) {
p_certificate := p_certificatesCaching[p_index].certificate;
return true;
}
return false;
}
function f_getCertificatesCachingItemSize(
in CertificatesCaching p_certificatesCaching
) return UInt8 {
return lengthof(p_certificatesCaching);
}
}// End of group certificatesCaching
} // 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 384-bit (48-byte) hash value
* @param p_toBeHashedData Data to be used to calculate the hash value
* @return The hash value
*/
external function fx_hashWithSha384(in octetstring p_toBeHashedData) return Oct48;
external function fx_test_hmac_sha256(in octetstring p_k, in octetstring p_m) return octetstring;
/**
* @desc Test function the validate AES128 CCM encryption based on IEEE Std 1609.2-20XX Annex D.6.1 AES-CCM-128
* @return The encrypted test
*/
external function fx_test_encrypt_aes_128_ccm_test(in octetstring p_k, in octetstring p_n, in octetstring p_pt) return octetstring;
/**
* @desc Test function the validate AES128 CCM decryption based on IEEE Std 1609.2-20XX Annex D.6.1 AES-CCM-128
* @return The decrypted test
*/
external function fx_test_decrypt_aes_128_ccm_test(in octetstring p_k, in octetstring p_n, in octetstring p_pt) return octetstring;
* @desc Produces a Elliptic Curve Digital Encrytion Algorithm (ECIES) encryption using Nist-P256 algorithm
* @param p_toBeEncryptedSecuredMessage The data to be encrypted
* @param p_recipientsPublicKeyX The Recipient's public encryption key X-coordinate
* @param p_recipientsPublicKeyY The Recipient's public encryption key Y-coordinate
* @param p_publicEphemeralKeyX The generated ephemeral key X-coordinate
* @param p_publicEphemeralKeyY The generated ephemeral key Y-coordinate
* @param p_encrypted_sym_key The encrypted AES 128 CCM symmetric key
* @param p_authentication_vector The tag of the AES 128 CCM symmetric key encryption
* @param p_nonce The nonce vector of the AES 128 CCM symmetric key encryption
* @return The encrypted message
external function fx_encryptWithEciesNistp256WithSha256(in octetstring p_toBeEncryptedSecuredMessage, in Oct32 p_recipientsPublicKeyX, in Oct32 p_recipientsPublicKeyY, out Oct32 p_publicEphemeralKeyX, out Oct32 p_publicEphemeralKeyY, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce) return octetstring;
* @desc Produces a Elliptic Curve Digital Encrytion Algorithm (ECIES) decryption using Nist-P256 algorithm
* @param p_encryptedSecuredMessage The data to be decrypted
* @param p_publicEphemeralKeyX The generated ephemeral key X-coordinate
* @param p_publicEphemeralKeyY The generated ephemeral key Y-coordinate
* @param p_encrypted_sym_key The encrypted AES 128 CCM symmetric key
* @param p_authentication_vector The tag of the AES 128 CCM symmetric key encryption
* @param p_nonce The nonce vector of the AES 128 CCM symmetric key encryption
* @return The decrypted message
external function fx_decryptWithEciesNistp256WithSha256(in octetstring p_encryptedSecuredMessage, in Oct32 p_privateEncKey, in Oct32 p_publicEphemeralKeyX, in Oct32 p_publicEphemeralKeyY, in Oct16 p_encrypted_sym_key, in Oct16 p_authentication_vector, in Oct12 p_nonce) return octetstring;
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
/**
* @desc Produces a Elliptic Curve Digital Encrytion Algorithm (ECIES) encryption using Brainpool-P256 algorithm
* @param p_toBeEncryptedSecuredMessage The data to be encrypted
* @param p_recipientsPublicKeyX The Recipient's public encryption key X-coordinate
* @param p_recipientsPublicKeyY The Recipient's public encryption key Y-coordinate
* @param p_publicEphemeralKeyX The generated ephemeral key X-coordinate
* @param p_publicEphemeralKeyY The generated ephemeral key Y-coordinate
* @param p_encrypted_sym_key The encrypted AES 128 CCM symmetric key
* @param p_authentication_vector The tag of the AES 128 CCM symmetric key encryption
* @param p_nonce The nonce vector of the AES 128 CCM symmetric key encryption
* @return The encrypted message
*/
external function fx_encryptWithEciesBrainpoolp256WithSha256(in octetstring p_toBeEncryptedSecuredMessage, in Oct32 p_recipientsPublicKeyX, in Oct32 p_recipientsPublicKeyY, out Oct32 p_publicEphemeralKeyX, out Oct32 p_publicEphemeralKeyY, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce) return octetstring;
/**
* @desc Produces a Elliptic Curve Digital Encrytion Algorithm (ECIES) decryption using Brainpool-P256 algorithm
* @param p_encryptedSecuredMessage The data to be decrypted
* @param p_publicEphemeralKeyX The generated ephemeral key X-coordinate
* @param p_publicEphemeralKeyY The generated ephemeral key Y-coordinate
* @param p_encrypted_sym_key The encrypted AES 128 CCM symmetric key
* @param p_authentication_vector The tag of the AES 128 CCM symmetric key encryption
* @param p_nonce The nonce vector of the AES 128 CCM symmetric key encryption
* @return The decrypted message
*/
external function fx_decryptWithEciesBrainpoolp256WithSha256(in octetstring p_encryptedSecuredMessage, in Oct32 p_privateEncKey, in Oct32 p_publicEphemeralKeyX, in Oct32 p_publicEphemeralKeyY, in Oct16 p_encrypted_sym_key, in Oct16 p_authentication_vector, in Oct12 p_nonce) return octetstring;
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
* @param p_toBeSignedSecuredMessage The data to be signed
* @param p_certificateIssuer The digest of the certificate issuer
* @param p_privateKey The private key
* @return The signature value
*/
external function fx_signWithEcdsaNistp256WithSha256(in Oct32 p_toBeSignedSecuredMessage, in HashedId8 p_certificateIssuer, in Oct32 p_privateKey) return octetstring;
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
* @param p_toBeSignedSecuredMessage The data to be signed
* @param p_certificateIssuer The digest of the certificate issuer
* @param p_privateKey The private key
* @return The signature value
*/
external function fx_signWithEcdsaBrainpoolp256WithSha256(in Oct32 p_toBeSignedSecuredMessage, in HashedId8 p_certificateIssuer, in Oct32 p_privateKey) return octetstring;
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
* @param p_toBeSignedSecuredMessage The data to be signed
* @param p_certificateIssuer The digest of the certificate issuer
* @param p_privateKey The private key
* @return The signature value
*/
external function fx_signWithEcdsaBrainpoolp384WithSha384(in Oct48 p_toBeSignedSecuredMessage, in HashedId8 p_certificateIssuer, in Oct48 p_privateKey) return octetstring;
/**
* @desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The digest of the certificate issuer
* @param p_signature The signature
* @param p_ecdsaNistp256PublicKeyCompressed The compressed public key (x coordinate only)
* @return true on success, false otherwise
*/
external function fx_verifyWithEcdsaNistp256WithSha256(in Oct32 p_toBeVerifiedData, in HashedId8 p_certificateIssuer, in octetstring p_signature, in Oct32 p_ecdsaNistp256PublicKeyCompressed, in integer p_compressedMode) return boolean;
* @desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The digest of the certificate issuer
* @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_1(in Oct32 p_toBeVerifiedData, in HashedId8 p_certificateIssuer, in octetstring p_signature, in Oct32 p_ecdsaNistp256PublicKeyX, in Oct32 p_ecdsaNistp256PublicKeyY) return boolean;
/**
* @desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The digest of the certificate issuer
* @param p_signature The signature
* @param p_ecdsaBrainpoolp256PublicKeyCompressed The compressed public key (x coordinate only)
* @return true on success, false otherwise
*/
external function fx_verifyWithEcdsaBrainpoolp256WithSha256(in Oct32 p_toBeVerifiedData, in HashedId8 p_certificateIssuer, in octetstring p_signature, in Oct32 p_ecdsaBrainpoolp256PublicKeyCompressed, in integer p_compressedMode) return boolean;
/**
* @desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The digest of the certificate issuer
* @param p_signature The signature
* @param p_ecdsaBrainpoolp256PublicKeyX The public key (x coordinate)
* @param p_ecdsaBrainpoolp256PublicKeyY The public key (y coordinate)
* @return true on success, false otherwise
*/
external function fx_verifyWithEcdsaBrainpoolp256WithSha256_1(in Oct32 p_toBeVerifiedData, in HashedId8 p_certificateIssuer, in octetstring p_signature, in Oct32 p_ecdsaBrainpoolp256PublicKeyX, in Oct32 p_ecdsaBrainpoolp256PublicKeyY) return boolean;
/**
* @desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The digest of the certificate issuer
* @param p_signature The signature
* @param p_ecdsaBrainpoolp384PublicKeyCompressed The compressed public key (x coordinate)
* @return true on success, false otherwise
*/
external function fx_verifyWithEcdsaBrainpoolp384WithSha384(in Oct48 p_toBeVerifiedData, in HashedId8 p_certificateIssuer, in octetstring p_signature, in Oct48 p_ecdsaBrainpoolp384PublicKeyCompressed, in integer p_compressedMode) return boolean;
/**
* @desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The digest of the certificate issuer
* @param p_ecdsaBrainpoolp384PublicKeyCompressed The compressed public key (x coordinate only)
* @return true on success, false otherwise
*/
external function fx_verifyWithEcdsaBrainpoolp384WithSha384_1(in Oct48 p_toBeVerifiedData, in HashedId8 p_certificateIssuer, in octetstring p_signature, in Oct48 p_ecdsaBrainpoolp384PublicKeyX, in Oct48 p_ecdsaBrainpoolp384PublicKeyY) 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)
* @param p_publicKeyCompressed The compressed public keys
* @param p_compressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
external function fx_generateKeyPair_nistp256(out Oct32 p_privateKey, out Oct32 p_publicKeyX, out Oct32 p_publicKeyY, out Oct32 p_publicKeyCompressed, out integer p_compressedMode) 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)
* @param p_publicKeyCompressed The compressed public keys
* @param p_compressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
external function fx_generateKeyPair_brainpoolp256(out Oct32 p_privateKey, out Oct32 p_publicKeyX, out Oct32 p_publicKeyY, out Oct32 p_publicKeyCompressed, out integer p_compressedMode) 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)
* @param p_publicKeyCompressed The compressed public keys
* @param p_compressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
external function fx_generateKeyPair_brainpoolp384(out Oct48 p_privateKey, out Oct48 p_publicKeyX, out Oct48 p_publicKeyY, out Oct48 p_publicKeyCompressed, out integer p_compressedMode) return boolean;
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;
external function fx_store_certificate(in charstring p_cert_id, in octetstring p_cert, in octetstring p_private_key, in octetstring p_public_key_x, in octetstring p_public_key_y, in octetstring p_public_key_compressed, in integer p_public_key_compressed_mode, in octetstring p_hashid8, in octetstring p_issuer, in template (omit) octetstring p_private_enc_key, in template (omit) octetstring p_public_enc_key_x, in template (omit) octetstring p_public_enc_key_y) 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 specified certificate digest
* @param p_certificateId the certificate identifier
* @param p_digest the expected certificate
* @return true on success, false otherwise
*/
external function fx_readCertificateDigest(in charstring p_certificateId, out HashedId8 p_digest) return boolean;
external function fx_readCertificateFromDigest(in HashedId8 p_digest, out charstring p_certificateId) return boolean;
* @desc Read the private keys for the specified certificate
* @param p_keysId the keys identifier
* @param p_signingPrivateKey the signing private key
* @return true on success, false otherwise
*/
external function fx_readSigningKey(in charstring p_keysId, out Oct32 p_signingPrivateKey) return boolean;
/**
* @desc Read the private keys for the specified certificate
* @param p_keysId the keys identifier
* @param p_encryptPrivateKey the encrypt private key
* @return true on success, false otherwise
*/
external function fx_readEncryptingKey(in charstring p_keysId, out Oct32 p_encryptingPrivateKey) 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;
* @desc Check if a polygonal region 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 SequenceOfRectangularRegion 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;
/**
* @desc Check if the location is inside an undefined 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_isLocationInsideOtherRegion(in octetstring p_region, in ThreeDLocation p_location) return boolean;
/**
* @desc Check that p_circular_region_1 circular region is included into p_circular_region_2 circular region
* @param p_circular_region_1 Circular region 1
* @param p_circular_region_2 Circular region 2
*
* @return true on success, false otherwise
*/
external function fx_areCirclesInside(in CircularRegion p_circular_region_1, in CircularRegion p_circular_region_2) return boolean;
/**
* @desc Check that p_rectanglar_region_1 rectangular region is included into p_rectanglar_region_2 rectangular region
* @param p_rectanglar_region_1 Rectangular region 1
* @param p_rectanglar_region_2 Rectangular region 2
*
* @return true on success, false otherwise
*/
external function fx_areRectanglesInside(in SequenceOfRectangularRegion p_rectanglar_region_1, in SequenceOfRectangularRegion p_rectanglar_region_2) return boolean;
/**
* @desc Check that p_polygonal_region_1 polygonal region is included into p_polygonal_region_2 polygonal region
* @param p_polygonal_region_1 Polygonal region 1
* @param p_polygonal_region_2 Polygonal region 2
*
* @return true on success, false otherwise
*/
external function fx_arePolygonsInside(in PolygonalRegion p_polygonal_region_1, in PolygonalRegion p_polygonal_region_2) return boolean;
* @desc Convert a spacial coordinate from DMS to Dms
* @param p_degrees The degrees (D)
* @param p_minutes The minutes (M)
* @param p_seconds The seconds (S)
* @param p_latlon The latitude/longitude: (N|S|E|W)
* @return The decimal coordinate on success, 0.0, otherwise
* @verdict Unchanged
*/
external function fx_dms2dd(in Int p_degrees, in Int p_minutes, in float p_seconds, in Oct1 p_latlon) return float;
} // End of group externalFunctions
in EtsiTs103097Certificate p_cert,
in EtsiTs103097Certificate p_cert_issuer
var ValidityPeriod v_cert_region, v_cert_issuer_region;
/* FIXME To be reviewed v_cert_issuer_region_result := f_getCertificateValidityRestriction(p_cert_issuer, e_region, v_cert_issuer_region);
if (f_getCertificateValidityRestriction(p_cert, e_region, v_cert_region) == false) {
if (v_cert_issuer_region_result == true) {
if (v_cert_issuer_region.validity.region.region_type != e_none) {
return false;
}
}
} else if (
(v_cert_issuer_region_result == true) and
(v_cert_issuer_region.validity.region.region_type != e_none)
if (v_cert_region.validity.region.region_type == e_circle) {
if (v_cert_issuer_region.validity.region.region_type == e_circle) {
// Check v_cert_region 'circle' is inside v_cert_issuer_region 'circle'
if (f_areCirclesInside(v_cert_region.validity.region.region.circular_region, v_cert_issuer_region.validity.region.region.circular_region) == false) {
log("*** " & testcasename() & ": FAIL: Issuer and issuing certificates circle area does not match ***");
return false;
}
}
} else if (v_cert_region.validity.region.region_type == e_rectangle) {
if (v_cert_issuer_region.validity.region.region_type == e_rectangle) {
// Check v_cert_region 'rectangle' is inside v_cert_issuer_region 'rectangle'
if (f_areRectanglesInside(v_cert_region.validity.region.region.rectangular_region, v_cert_issuer_region.validity.region.region.rectangular_region) == false) {
log("*** " & testcasename() & ": FAIL: Issuer and issuing certificates rectangle area does not match ***");
return false;
}
}
} else if (v_cert_region.validity.region.region_type == e_polygon) {
if (v_cert_issuer_region.validity.region.region_type == e_polygon) {
// Check v_cert_region 'polygon' is inside v_cert_issuer_region 'polygon'
if (f_arePolygonsInside(v_cert_region.validity.region.region.polygonal_region, v_cert_issuer_region.validity.region.region.polygonal_region) == false) {
log("*** " & testcasename() & ": FAIL: Issuer and issuing certificates polygon area does not match ***");
return false;
}
}
} else if (v_cert_region.validity.region.region_type == e_id) {
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
// Check id_region
if (not match (v_cert_region.validity.region, mw_geographicRegion_identified(mw_identifiedRegion_iso3166_any))) {
log("*** " & testcasename() & ": FAIL: Identified region is not conformed to ISO 3166-1 ***");
return false;
}
if (not match (v_cert_region.validity.region, mw_geographicRegion_identified(mw_identifiedRegion_un_stats_any))) {
log("*** " & testcasename() & ": FAIL: Identified region is not conformed to United Nations Statistics Division ***");
return false;
}
// Check region_dictionary
if (not match (v_cert_region.validity.region.region.id_region.region_dictionary, v_cert_issuer_region.validity.region.region.id_region.region_dictionary)) {
log("*** " & testcasename() & ": FAIL: Issuer and issuing 'region_dictionary' field does not match ***");
return false;
}
// Check region_identifier
if (not match (v_cert_region.validity.region.region.id_region.region_identifier, v_cert_issuer_region.validity.region.region.id_region.region_identifier)) {
log("*** " & testcasename() & ": FAIL: Issuer and issuing 'region_identifier' field does not match ***");
return false;
}
// Check local_region
if (
(not match (v_cert_issuer_region.validity.region.region.id_region.local_region, v_cert_region.validity.region.region.id_region.local_region)) or
(not match (v_cert_issuer_region.validity.region.region.id_region.local_region, 0))
) {
log("*** " & testcasename() & ": FAIL: Issuer and issuing 'local_region' field does not match ***");
return true;
} // End of function f_checkRegionValidityRestiction
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
* @desc Check that p_circular_region_1 circular region is included into p_circular_region_2 circular region
* @param p_circular_region_1 Circular region 1
* @param p_circular_region_2 Circular region 2
*
* @return true on success, false otherwise
*/
function f_areCirclesInside(
in CircularRegion p_circular_region_1,
in CircularRegion p_circular_region_2
) return boolean {
return fx_areCirclesInside(p_circular_region_1, p_circular_region_2);
}
/**
* @desc Check that p_rectanglar_region_1 rectangular region is included into p_rectanglar_region_2 rectangular region
* @param p_rectanglar_region_1 Rectangular region 1
* @param p_rectanglar_region_2 Rectangular region 2
*
* @return true on success, false otherwise
*/
function f_areRectanglesInside(
in SequenceOfRectangularRegion p_rectanglar_region_1,
in SequenceOfRectangularRegion p_rectanglar_region_2
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
) return boolean {
return fx_areRectanglesInside(p_rectanglar_region_1, p_rectanglar_region_2);
}
/**
* @desc Check that p_polygonal_region_1 polygonal region is included into p_polygonal_region_2 polygonal region
* @param p_polygonal_region_1 Polygonal region 1
* @param p_polygonal_region_2 Polygonal region 2
*
* @return true on success, false otherwise
*/
function f_arePolygonsInside(
in PolygonalRegion p_polygonal_region_1,
in PolygonalRegion p_polygonal_region_2
) return boolean {
return fx_arePolygonsInside(p_polygonal_region_1, p_polygonal_region_2);
}
/**
* @desc Check that given location is valid
* @param p_location location to be checked
* @return true on success, false otherwise
*/
//FIXME RGY Titan doesn't support dot notation after valueof at the moment
// (valueof(p_location).longitude != c_maxLongitude + 1) and
// (valueof(p_location).latitude != c_maxLatitude + 1);
(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)
* @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
//FIXME RGY Titan doesn't support dot notation after valueof at the moment
// 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
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
in template (value) SequenceOfRectangularRegion p_region
var integer v_i, v_j;
var boolean v_found;
for (v_i := 0; v_i < lengthof(p_region); v_i := v_i + 1) {
var PolygonalRegion v_region_base;
f_convertRectangularRegionIntoPolygonalRegion(valueof(p_region[v_i]), v_region_base);
v_found := false;
for (v_j := 0; v_j < lengthof(p_region); v_j := v_j + 1) {
if (v_j != v_i) {
var PolygonalRegion v_region;
f_convertRectangularRegionIntoPolygonalRegion(valueof(p_region[v_j]), v_region);
if (f_isPolygonalRegionInside(v_region, v_region_base) == true) {
v_found := true;
}
}
} // End of 'for' statement
if (v_found == false) {
return false;
}
} // End of 'for' statement
} // End of function f_isContinuousRectangularRegions
* @desc Check if a polygonal region 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) SequenceOfRectangularRegion p_parent,
in template (value) SequenceOfRectangularRegion p_region
var integer v_i, v_j;
for (v_i := 0; v_i < lengthof(p_parent); v_i := v_i + 1) {
var PolygonalRegion v_region_parent, v_region;
f_convertRectangularRegionIntoPolygonalRegion(valueof(p_parent[v_i]), v_region_parent);
for (v_j := 0; v_j < lengthof(p_parent); v_j := v_j + 1) {
f_convertRectangularRegionIntoPolygonalRegion(valueof(p_region[v_j]), v_region);
if (f_isPolygonalRegionInside(v_region, v_region_parent) == true) {
return true;
}
} // End of 'for' statement
} // End of 'for' statement
return false;
} // End of function f_isRectangularRegionsInside
/**
* @desc Convert a rectangular region into a polygonal region
* @param p_region The rectangular regions to convert
* @return
* @verdict
*/
function f_convertRectangularRegionIntoPolygonalRegion(
in template (value) RectangularRegion p_rectangular_region,
out PolygonalRegion p_region
) return boolean {
// Convert rectangular regions to polygons and check polygons
p_region[0] := valueof(p_rectangular_region.northWest);
p_region[1] := {
valueof(p_rectangular_region.northWest.latitude) + valueof(p_rectangular_region.southEast.latitude),
valueof(p_rectangular_region.northWest.longitude)
};
p_region[2] := valueof(p_rectangular_region.southEast);
p_region[3] := {
valueof(p_rectangular_region.northWest.latitude),
valueof(p_rectangular_region.northWest.longitude) + valueof(p_rectangular_region.southEast.longitude)
};
log("f_convertRectangularRegionIntoPolygonalRegion: DEBUG: Northwest location is invalid in rect ", p_region);
return true;
} // End of function
* @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
*/
// 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 region 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
// Sanity check
if (not isbound(p_parent) or not isbound(p_region) or (lengthof(p_parent) == 0) or (lengthof(p_region) == 0)) {
return false;
}
return fx_isPolygonalRegionInside(valueof(p_parent), valueof(p_region));
} // End of function f_isPolygonalRegionInside
function f_isIdentifiedRegionInside(
in template (value) UInt16 p_parent,
in template (value) UInt16 p_region
} // 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;
if (ischosen(p_region.circularRegion)) {
v_ret := f_isLocationInsideCircularRegion(valueof(p_region.circularRegion), p_location);
} else if (ischosen(p_region.rectangularRegion)) {
v_ret := f_isLocationInsideRectangularRegion(valueof(p_region.rectangularRegion), p_location);
} else if (ischosen(p_region.polygonalRegion)) {
v_ret := f_isLocationInsidePolygonalRegion(valueof(p_region.polygonalRegion), p_location);
} else if (ischosen(p_region.identifiedRegion)) {
for (var integer v_i := 0; v_i < lengthof(p_region.identifiedRegion); v_i := v_i + 1) {
if (f_isLocationInsideIdentifiedRegion(valueof(p_region.identifiedRegion[v_i]), p_location) == true) {
v_ret := true;
break;
}
} // End of 'for' statement
} // 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
// 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) SequenceOfRectangularRegion p_region,
// Sanity check
if (not isbound(p_region) or not isbound(p_location) or (lengthof(p_region) == 0)) {
return false;
}
// log("f_isLocationInsideRectangularRegion: p_polygonalArea: ", p_region);
// log("f_isLocationInsideRectangularRegion: p_location: ", p_location);
return fx_isLocationInsideRectangularRegion(valueof(p_region), valueof(p_location));
} // End of function f_isLocationInsideRectangularRegion
/**
* @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
*/
function f_isLocationInsidePolygonalRegion(
in template (value) PolygonalRegion p_region,
in template (value) ThreeDLocation p_location
// Sanity check
if (not isbound(p_region) or not isbound(p_location) or (lengthof(p_region) == 0)) {
return false;
}
// log("f_isLocationInsidePolygonalRegion: p_polygonalArea: ", p_region, " - ", valueof(p_region));
// log("f_isLocationInsidePolygonalRegion: p_location: ", p_location, " - ", valueof(p_location));
return fx_isLocationInsidePolygonalRegion(valueof(p_region), valueof(p_location));
} // End of function f_isLocationInsidePolygonalRegion
/**
* @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
*/
function f_isLocationInsideIdentifiedRegion(
in template (value) IdentifiedRegion p_region,
in template (value) ThreeDLocation p_location
// Sanity check
if (not isbound(p_region) or not isbound(p_location)) {
return false;
}
return fx_isLocationInsideIdentifiedRegion(valueof(p_region), valueof(p_location));
} // End of function f_isLocationInsideIdentifiedRegion
/**
* @desc Check if the location is inside an undefined region
* @param p_region The identified region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_isLocationInsideOtherRegion(
in template (value) octetstring p_region,
in template (value) ThreeDLocation p_location
// Sanity check
if (valueof(p_region) == ''O) {
return false;
}
return fx_isLocationInsideOtherRegion(valueof(p_region), valueof(p_location));
} // End of function f_isLocationInsideOtherRegion
* @desc Convert a spacial coordinate from DMS to Dms
* @param p_degrees The degrees (D)
* @param p_minutes The minutes (M)
* @param p_seconds The seconds (S)
* @param p_latlon The latitude/longitude: (N|S|E|W)
* @return The decimal coordinate on success, 0.0, otherwise
* @verdict Unchanged
*/
in integer p_degrees,
in integer p_minutes,
in float p_seconds,
in charstring p_latlon
// Sanity checks
if (lengthof(p_latlon) != 1) {
return 0.0;
} else if ((p_latlon != "N") and (p_latlon != "S") and (p_latlon != "E") and (p_latlon != "W")) {
return 0.0;
}
return fx_dms2dd(p_degrees, p_minutes, p_seconds, v_latlon);
} // End of function f_dms2dd
/**
* @desc Convert the latitude from float to int
* @param p_latitude The latitude to be converted. Significand length shall be 7 digits length
* @return The converted latitude
* @verdict Unchanged
*/
return float2int(p_latitude * 10000000.0); // Significand length shall be 7 digits length
}
/**
* @desc Convert the longitude from float to int
* @param p_longitude The longitude to be converted. Significand length shall be 6 digits length
* @return The converted longitude
* @verdict Unchanged
*/
return float2int(p_longitude * 1000000.0); // Significand length shall be 6 digits length
}
} // End of module LibItsSecurity_Functions