LibItsPki_Functions.ttcn 268 KB
Newer Older
                                                                              substr(v_tbs_signed, 32, 32)
                                                                              )
                                                         )
                               );
      } else if (PX_VE_ALG == e_brainpool_p256_r1) {
        v_signature := valueof(
                               m_signature_ecdsaBrainpoolP256r1(
                                                                m_ecdsaP256Signature(
                                                                                     m_eccP256CurvePoint_x_only(
                                                                                                                substr(v_tbs_signed, 0, 32)
                                                                                                                ),
                                                                                     substr(v_tbs_signed, 32, 32)
                                                                                     )
                                                                )
                               );
      } else if (PX_VE_ALG == e_brainpool_p384_r1) {
        v_signature := valueof(
                               m_signature_ecdsaBrainpoolP384r1(
                                                                m_ecdsaP384Signature(
                                                                                     m_eccP384CurvePoint_x_only(
                                                                                                                substr(v_tbs_signed, 0, 48)
                                                                                                                ),
                                                                                     substr(v_tbs_signed, 48, 48)
                                                                                     )
                                                                )
                               );
      }
      log("f_generate_inner_ec_request_signed_for_pop: v_signature= ", v_signature);
garciay's avatar
garciay committed
      p_inner_ec_request_signed_for_pop := valueof(
                                                   m_etsiTs103097Data_signed(
                                                                             m_signedData(
                                                                                          sha256,
                                                                                          v_tbs,
                                                                                          m_signerIdentifier_self,
      
      log("<<< f_generate_inner_ec_request_signed_for_pop: p_inner_ec_request_signed_for_pop= ", p_inner_ec_request_signed_for_pop);
garciay's avatar
garciay committed
      return true;
    } // End of function f_generate_inner_ec_request_signed_for_pop
Yann Garcia's avatar
Yann Garcia committed

    function f_verify_inner_ec_request_signed_for_pop(
                                                      in EtsiTs102941Data p_etsi_ts_102941_data,
                                                      out InnerEcRequest p_inner_ec_request
                                                      ) return boolean {
      var bitstring v_msg_bit;

      log(">>> f_verify_inner_ec_request_signed_for_pop: ", p_etsi_ts_102941_data);
      
      // 1. Decode content
      v_msg_bit := oct2bit(p_etsi_ts_102941_data.content.enrolmentRequest.content.signedData.tbsData.payload.data.content.unsecuredData);
      if (decvalue(v_msg_bit, p_inner_ec_request) != 0) {
        log("f_verify_inner_ec_request_signed_for_pop: Failed to decode InnerEcRequest");
        return false;
      } else {
        log("f_verify_inner_ec_request_signed_for_pop: v_inner_ec_request= ", p_inner_ec_request);

        // 2. Verify the InnerEcRequestSignedForPop signature
        // TODO
Yann Garcia's avatar
Yann Garcia committed
      }
      
      return true;
    } // End of function f_verify_inner_ec_request_signed_for_pop
    function f_generate_inner_ec_response(
                                          in octetstring p_inner_ec_request_hash,
                                          in EtsiTs103097Certificate p_certificate,
                                          out InnerEcResponse p_inner_ec_response
                                         ) return boolean {
      // Local variables
      
      // Build the Proof of Possession InnerEcResponse
      p_inner_ec_response := valueof(
                                     m_innerEcResponse_ok(
                                                          substr(p_inner_ec_request_hash, 0, 16),
                                                          p_certificate
                                                          )
                                     );
      
      return true;
    } // End of function f_generate_inner_ec_response
    
garciay's avatar
garciay committed
  } // End of group inner_ec_xxx

  group inner_at_xxx {

    function f_generate_inner_at_request(
                                         in Certificate p_aa_certificate,
YannGarcia's avatar
YannGarcia committed
                                         in SecurityAlg p_enc_algo := PX_EC_ALG_FOR_EC_SIGN,
                                         in Oct8 p_aa_hashed_id8,
                                         in Certificate p_ea_certificate,
                                         in octetstring p_salt,
                                         in Oct8 p_ea_hashed_id8,
                                         in Certificate p_ec_certificate,
                                         in octetstring p_ec_private_key,
Yann Garcia's avatar
Yann Garcia committed
                                         out octetstring p_private_key,
                                         out octetstring p_public_key_compressed,
                                         out integer p_compressed_key_mode,
                                         out octetstring p_private_enc_key,
                                         out octetstring p_public_compressed_enc_key,
                                         out integer p_compressed_enc_key_mode,
                                         out InnerAtRequest p_inner_at_request
                                         ) return boolean {
      // Local variables
Yann Garcia's avatar
Yann Garcia committed
      var octetstring v_public_key_x;
      var octetstring v_public_key_y;
      var octetstring v_public_enc_key_x;
      var octetstring v_public_enc_key_y;
      var bitstring v_enc_value;
      var octetstring v_ec_hash;
      var PublicVerificationKey v_public_verification_key;
      var BasePublicEncryptionKey v_public_encryption_key;
      var Oct8 v_ec_hashed_id8;
Yann Garcia's avatar
Yann Garcia committed
      var octetstring public_enc_key_x;
      var octetstring public_enc_key_y;
      var Oct32 v_hmac_key;
      var PublicVerificationKey v_verification_tag;
      var PublicEncryptionKey v_encryption_tag;
      var octetstring v_encoded_tag;
      var Oct16 v_key_tag;
      var octetstring v_hash_shared_at_request;
      var template (value) ToBeSignedData v_tbs;
      var octetstring v_tbs_signed;
      var Ieee1609Dot2Data v_signed_at_signature;
      var template (value) EccP256CurvePoint v_eccP256_curve_point;
      var HashAlgorithm v_hashId;
      var Signature v_signature;
      var SequenceOfPsidSsp v_appPermissions := { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs
        valueof(m_appPermissions(c_its_aid_CAM, { bitmapSsp := PX_INNER_AT_CERTFICATE_BITMAP_SSP_CAM })),
        valueof(m_appPermissions(c_its_aid_DENM, { bitmapSsp := PX_INNER_AT_CERTFICATE_BITMAP_SSP_DENM }))
YannGarcia's avatar
YannGarcia committed

      log(">>> f_generate_inner_at_request: p_enc_algo=", p_enc_algo);

Yann Garcia's avatar
Yann Garcia committed
      // Generate verification keys for the certificate to be requested
      if (f_generate_key_pair(p_private_key, v_public_key_x, v_public_key_y, p_public_key_compressed, p_compressed_key_mode) == false) {
        log("f_generate_inner_at_request: Failed to generate verification key");
        return false;
      }
      log ("f_generate_inner_at_request: AT verification private key: ", p_private_key);
      log ("f_generate_inner_at_request: AT verification public compressed key: ", p_public_key_compressed);
      log ("f_generate_inner_at_request: AT verification public compressed mode: ", p_compressed_key_mode);
      // Generate encryption keys for the certificate to be requested
      if (PX_INCLUDE_ENCRYPTION_KEYS) {
YannGarcia's avatar
YannGarcia committed
        if (f_generate_key_pair_for_encryption(p_enc_algo, p_private_enc_key, v_public_enc_key_x, v_public_enc_key_y, p_public_compressed_enc_key, p_compressed_enc_key_mode) == false) {
Yann Garcia's avatar
Yann Garcia committed
          log("f_generate_inner_at_request: Failed to generate encryption key");
          return false;
        } else {
          log ("f_generate_inner_at_request: AT encryption private key: ", p_private_enc_key);
          log ("f_generate_inner_at_request: AT encryption public compressed key: ", p_public_compressed_enc_key);
          log ("f_generate_inner_at_request: AT encryption public compressed mode: ", p_compressed_enc_key_mode);
Yann Garcia's avatar
Yann Garcia committed
        }
      } else {
        p_private_enc_key := ''O;
        v_public_enc_key_x := ''O;
        v_public_enc_key_y := ''O;
Yann Garcia's avatar
Yann Garcia committed
        p_public_compressed_enc_key := ''O;
        p_compressed_enc_key_mode := -1;
      }
      
      // Generate 32 octets length secret key
      v_hmac_key := f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 12));
      log("f_generate_inner_at_request: v_hmac_key= ", v_hmac_key);
      // Generate tag based on the concatenation of verification keys & encryption keys
      if (f_generate_key_tag(p_public_key_compressed, p_compressed_key_mode, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_encoded_tag) == false) {
        log("f_generate_inner_at_request: Failed to generate Key tag");
        return false;
      log("f_generate_inner_at_request: v_encoded_tag= ", v_encoded_tag);
      v_key_tag := substr(
                          fx_hmac_sha256( // TODO Rename and use a wrapper function
                                         v_hmac_key,
                                         v_encoded_tag
                                         ),
                          0,
                          16); // Leftmost 128 bits of the HMAC-SHA256 tag computed previously
      log("f_generate_inner_at_request: v_key_tag= ", v_key_tag);

      // Build the SharedAtRequest
      p_inner_at_request.sharedAtRequest := valueof(
                                                    m_shared_at_request(
                                                                        p_ea_hashed_id8, // eaId identifies the EA certificate shared with EA entity
                                                                        v_key_tag, // Calculated keyTag
                                                                                m_certificate_subject_attributes( // FIXME Review subjectPermissions
YannGarcia's avatar
YannGarcia committed
                                                                                                                 v_appPermissions,
                                                                                                                 p_ec_certificate.toBeSigned.certRequestPermissions,
                                                                                                                 { none_ := NULL },//p_ec_certificate.toBeSigned.id,
                                                                                                                 p_ec_certificate.toBeSigned.validityPeriod,
                                                                                                                 p_ec_certificate.toBeSigned.region,
                                                                                                                 p_ec_certificate.toBeSigned.assuranceLevel
                                                                                                                  ))) // Desired attributes
                                                    );
      // Calculate the hash of the SharedAtRequest
      v_hash_shared_at_request := f_hashWithSha256(bit2oct(encvalue(p_inner_at_request.sharedAtRequest)));
      log("f_generate_inner_at_request: v_hash_shared_at_request= ", v_hash_shared_at_request);
      
      // Build the ETsiTs103097Data-SignedExternalPayload
      v_tbs := m_toBeSignedData(
                                m_signedDataPayload_ext(v_hash_shared_at_request), // Payload containing extDataHash
                                m_headerInfo_inner_pki_request( // HeaderInfo
                                                               -,
                                                               (f_getCurrentTime()) * 1000) //us
      log("f_generate_inner_at_request: v_tbs= ", v_tbs);
YannGarcia's avatar
YannGarcia committed
      
      // Calculate the whole certificate SHA
      v_enc_value := encvalue(p_ec_certificate);
      if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1)) {
        v_ec_hash := f_hashWithSha384(bit2oct(v_enc_value));
        v_ec_hashed_id8 := f_HashedId8FromSha384(v_ec_hash);
      } else {
        v_ec_hash := f_hashWithSha256(bit2oct(v_enc_value));
        v_ec_hashed_id8 := f_HashedId8FromSha256(v_ec_hash);
      }
      log("f_generate_inner_at_request: v_ec_hash= ", v_ec_hash);
      
      // Signed ToBeSigned payload using the private key of EC certificate obtained from Enrolment request
      // In case of ITS-S privacy, v_signed_at_signature contained the data to be encrypted
      if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1)) {
        v_hashId := sha384;
        v_tbs_signed := f_signWithEcdsaBrainpoolp384WithSha384(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
        v_signature := valueof(
                               m_signature_ecdsaBrainpoolP384r1(
                                                                m_ecdsaP384Signature(
                                                                                     m_eccP384CurvePoint_x_only(
                                                                                                                substr(v_tbs_signed, 0, 48)
                                                                                                                ),
                                                                                     substr(v_tbs_signed, 48, 48)
                                                                                     )
                                                                )
                                                        );
      } else {
        v_hashId := sha256;
        if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1)) {
          v_tbs_signed := f_signWithEcdsaBrainpoolp256WithSha256(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
          v_signature := valueof(
                                 m_signature_ecdsaBrainpoolP256r1(
                                                                  m_ecdsaP256Signature(
                                                                                       m_eccP256CurvePoint_x_only(
                                                                                                                  substr(v_tbs_signed, 0, 32)
                                                                                                                  ),
                                                                                       substr(v_tbs_signed, 32, 32)
                                                                                       )
                                                                  )
                                 );
        } else if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256)) {
          v_tbs_signed := f_signWithEcdsaNistp256WithSha256(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
          v_signature := valueof(
                                 m_signature_ecdsaNistP256(
                                                           m_ecdsaP256Signature(
                                                                                m_eccP256CurvePoint_x_only(
                                                                                                           substr(v_tbs_signed, 0, 32)
                                                                                                           ),
                                                                                substr(v_tbs_signed, 32, 32)
                                                                                )
                                                           )
                                 );
        } else {
          // Error
          log("f_generate_inner_at_request: Failed to process signature");
          return false;
        }
      v_signed_at_signature := valueof(
                                       m_etsiTs103097Data_signed(
                                                                 m_signedData(
                                                                              m_signerIdentifier_digest(v_ec_hashed_id8), // Signer is thehasheId8 of the EC certificate obtained from Enrolment request
      log("f_generate_inner_at_request: v_signed_at_signature= ", v_signed_at_signature);
YannGarcia's avatar
YannGarcia committed
      log("f_generate_inner_at_request: p_ea_certificate= ", p_ea_certificate);
      
      if (PICS_ITS_S_WITH_PRIVACY) { // Build EtsiTs102097Data-Encrypted structure
        var octetstring v_public_enc_key;
        var integer v_compressed_mode;
        var Oct12 v_nonce;
        var Oct16 v_authentication_vector;
        var Oct16 v_aes_sym_key;
        var Oct16 v_encrypted_sym_key;
        var HashedId8 v_recipientId;
        var octetstring v_public_compressed_ephemeral_key;
        var integer v_public_compressed_ephemeral_mode;
        var octetstring v_enc_signed_ec_signature;
        var EncryptedDataEncryptionKey v_encrypted_data_encryption_key;
        // Use EA certificate for the encryption
YannGarcia's avatar
YannGarcia committed
        if (p_enc_algo == e_nist_p256) {
          if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0)) {
            v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0;
            v_compressed_mode := 0;
          } else if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1)) {
            v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1;
            v_compressed_mode := 1;
          } else {
            log("f_generate_inner_at_request: Wrong NistP256 encryption variant");
            return false;
          }
          v_enc_signed_ec_signature := f_encryptWithEciesNistp256WithSha256(bit2oct(encvalue(v_signed_at_signature)), v_public_enc_key, v_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, PICS_SEC_FIXED_KEYS);
          if (v_public_compressed_ephemeral_mode == 0) {
            v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key));
            v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key));
          v_encrypted_data_encryption_key := valueof(
                                                     m_encryptedDataEncryptionKey_eciesNistP256(
                                                                                                m_evciesP256EncryptedKey(
                                                                                                                         v_eccP256_curve_point,
                                                                                                                         v_encrypted_sym_key,
                                                                                                                         v_authentication_vector
                                                                                                                         )));
YannGarcia's avatar
YannGarcia committed
        } else if (p_enc_algo == e_brainpool_p256_r1) {
          if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0)) {
            v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0;
            v_compressed_mode := 0;
          } else if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1)) {
            v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1;
            v_compressed_mode := 1;
          } else {
            log("f_generate_inner_at_request: Wrong BrainpoolP256r1 encryption variant");
            return false;
          }
          v_enc_signed_ec_signature := f_encryptWithEciesBrainpoolp256WithSha256(bit2oct(encvalue(v_signed_at_signature)), v_public_enc_key, v_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, PICS_SEC_FIXED_KEYS);
          if (v_public_compressed_ephemeral_mode == 0) {
            v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key));
Yann Garcia's avatar
Yann Garcia committed
          } else {
            v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key));
          v_encrypted_data_encryption_key := valueof(
                                                     m_encryptedDataEncryptionKey_eciesBrainpoolP256r1(
                                                                                                       m_evciesP256EncryptedKey(
                                                                                                                                v_eccP256_curve_point,
                                                                                                                                v_encrypted_sym_key,
                                                                                                                                v_authentication_vector
                                                                                                                                )));
garciay's avatar
garciay committed
        } else {
          log("f_generate_inner_at_request: Wrong encryption variant");
garciay's avatar
garciay committed
          return false;
        }
        log("f_generate_inner_at_request: v_encrypted_data_encryption_key= ", v_encrypted_data_encryption_key);
        v_recipientId := p_ea_hashed_id8; // RecipientId is the HashedId8 of the EA certificate
        log("f_generate_inner_at_request: v_recipientId= ", v_recipientId);
        // Fill Certificate template with the public compressed keys (canonical form)
        p_inner_at_request.ecSignature := valueof(
                                                  m_ec_signature(
                                                                 m_etsiTs103097Data_encrypted(
                                                                                              m_encryptedData(
                                                                                                              {
                                                                                                                m_recipientInfo_certRecipInfo(
                                                                                                                                              m_pKRecipientInfo(
                                                                                                                                                                v_recipientId,
                                                                                                                                                                
                                                                                                                                                                v_encrypted_data_encryption_key                                                                                                                                                            ))
                                                                                                                },
                                                                                                              m_SymmetricCiphertext_aes128ccm(
                                                                                                                                              m_aesCcmCiphertext(
                                                                                                                                                                 v_enc_signed_ec_signature
                                                                                                                                                                 )
                                                                                                                                              )
                                                                                                              )
      } else { // Skip the encryption, alowed to be re-identified by the AA
        p_inner_at_request.ecSignature := valueof(m_ec_signature_ext_payload(v_signed_at_signature));
      // Build the InnerAtRequest, EcSignature field is already set
      if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256)) {
        if (p_compressed_key_mode == 0) {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_x));
        } else {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_x));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaNistP256(v_eccP256_curve_point));
      } else if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1)) {
        if (p_compressed_key_mode == 0) {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_x));
        } else {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_x));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP256r1(v_eccP256_curve_point));
        var EccP384CurvePoint v_eccP384_curve_point;
        if (p_compressed_key_mode == 0) {
          v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_0(v_public_key_x));
        } else {
          v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_1(v_public_key_x));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP384r1(v_eccP384_curve_point));
      if (PX_INCLUDE_ENCRYPTION_KEYS) {
        var template (value) EccP256CurvePoint v_enc_eccP256_curve_point;
        
        if (p_compressed_enc_key_mode == 0) {
          v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_0(v_public_enc_key_x);
        } else {
          v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_1(v_public_enc_key_x);
        }
YannGarcia's avatar
YannGarcia committed
        if (p_enc_algo == e_nist_p256) {
          v_public_encryption_key := valueof(m_publicEncryptionKey_eciesNistP256(v_enc_eccP256_curve_point));
        } else {
          v_public_encryption_key := valueof(m_publicEncryptionKey_eciesBrainpoolP256r1(v_enc_eccP256_curve_point));
        }
        p_inner_at_request.publicKeys := valueof( // The freshly generated public verification & encrypition keys to be used for the requested AT certificate
                                                 m_publicKeys(
                                                              v_public_verification_key,
                                                              m_encryptionKey( // FIXME Encryption keys could be optional
                                                                              -,
                                                                              v_public_encryption_key
                                                                              )
                                                              )
                                                  );
      } else {
        p_inner_at_request.publicKeys := valueof( // The freshly generated public verification keys to be used for the requested AT certificate
                                                 m_publicKeys(
                                                              v_public_verification_key
      p_inner_at_request.hmacKey := v_hmac_key;
      log("f_generate_inner_at_request: p_inner_at_request= ", p_inner_at_request);
      
      return true;
    } // End of function f_generate_inner_at_request
    
    function f_generate_inner_at_request_with_wrong_parameters(
                                                               in Certificate p_aa_certificate,
YannGarcia's avatar
YannGarcia committed
                                                               in SecurityAlg p_enc_algo := PX_EC_ALG_FOR_AT,
                                                               in Oct8 p_aa_hashed_id8,
                                                               in Certificate p_ea_certificate,
                                                               in octetstring p_salt,
                                                               in Oct8 p_ea_hashed_id8,
                                                               in Certificate p_ec_certificate,
                                                               in octetstring p_ec_private_key,
                                                               in boolean p_alter_hmac := false,
                                                               in boolean p_alter_signer_digest := false,
                                                               in template (omit) Time32 p_start := omit,
                                                               in template (omit) Duration p_duration := omit,
YannGarcia's avatar
YannGarcia committed
                                                               in template (omit) Time64 p_generation_time := omit,
                                                               out octetstring p_private_key,
                                                               out octetstring p_public_key_compressed,
                                                               out integer p_compressed_key_mode,
                                                               out octetstring p_private_enc_key,
                                                               out octetstring p_public_compressed_enc_key,
                                                               out integer p_compressed_enc_key_mode,
                                                               out InnerAtRequest p_inner_at_request
                                                               ) return boolean {
      // Local variables
      var octetstring v_public_key_x;
      var octetstring v_public_key_y;
      var octetstring v_public_enc_key_x;
      var octetstring v_public_enc_key_y;
      var bitstring v_enc_value;
      var octetstring v_ec_hash;
      var PublicVerificationKey v_public_verification_key;
      var BasePublicEncryptionKey v_public_encryption_key;
      var Oct8 v_ec_hashed_id8;
      var octetstring public_enc_key_x;
      var octetstring public_enc_key_y;
      var Oct32 v_hmac_key;
      var PublicVerificationKey v_verification_tag;
      var PublicEncryptionKey v_encryption_tag;
      var octetstring v_encoded_tag;
      var Oct16 v_key_tag;
      var octetstring v_hash_shared_at_request;
      var template (value) ToBeSignedData v_tbs;
      var octetstring v_tbs_signed;
      var Ieee1609Dot2Data v_signed_at_signature;
      var template (value) EccP256CurvePoint v_eccP256_curve_point;
      var template (value) EccP256CurvePoint v_enc_eccP256_curve_point;
      var HashAlgorithm v_hashId;
      var Signature v_signature;
      var Time32 v_start;
      var Duration v_duration;
YannGarcia's avatar
YannGarcia committed
      var SequenceOfPsidSsp v_appPermissions := { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs
        valueof(m_appPermissions(c_its_aid_CAM, { bitmapSsp := PX_INNER_AT_CERTFICATE_BITMAP_SSP_CAM })),
        valueof(m_appPermissions(c_its_aid_DENM, { bitmapSsp := PX_INNER_AT_CERTFICATE_BITMAP_SSP_DENM }))
YannGarcia's avatar
YannGarcia committed

      log("f_generate_inner_at_request_with_wrong_parameters: p_enc_algo=", p_enc_algo);

      // Generate verification keys for the certificate to be requested
      if (f_generate_key_pair(p_private_key, v_public_key_x, v_public_key_y, p_public_key_compressed, p_compressed_key_mode) == false) {
        log("f_generate_inner_at_request_with_wrong_parameters: Failed to generate verification key");
        return false;
      }
      log ("f_generate_inner_at_request_with_wrong_parameters: AT verification private key: ", p_private_key);
      log ("f_generate_inner_at_request_with_wrong_parameters: AT verification public compressed key: ", p_public_key_compressed);
      log ("f_generate_inner_at_request_with_wrong_parameters: AT verification public compressed mode: ", p_compressed_key_mode);
      // Generate encryption keys for the certificate to be requested
      if (PX_INCLUDE_ENCRYPTION_KEYS) {
YannGarcia's avatar
YannGarcia committed
        if (f_generate_key_pair_for_encryption(p_enc_algo, p_private_enc_key, v_public_enc_key_x, v_public_enc_key_y, p_public_compressed_enc_key, p_compressed_enc_key_mode) == false) {
          log("f_generate_inner_at_request_with_wrong_parameters: Failed to generate encryption key");
          return false;
        } else {
          log ("f_generate_inner_at_request_with_wrong_parameters: AT encryption private key: ", p_private_enc_key);
          log ("f_generate_inner_at_request_with_wrong_parameters: AT encryption public compressed key: ", p_public_compressed_enc_key);
          log ("f_generate_inner_at_request_with_wrong_parameters: AT encryption public compressed mode: ", p_compressed_enc_key_mode);
        }
      } else {
        p_private_enc_key := ''O;
        v_public_enc_key_x := ''O;
        v_public_enc_key_y := ''O;
        p_public_compressed_enc_key := ''O;
        p_compressed_enc_key_mode := -1;
      }
      
      // Calculate the whole certificate SHA
      v_enc_value := encvalue(p_ec_certificate);
      if (ischosen(p_ec_certificate.issuer.sha256AndDigest)) {
        v_ec_hash := f_hashWithSha256(bit2oct(v_enc_value));
        v_ec_hashed_id8 := f_HashedId8FromSha256(v_ec_hash);
      } else {
        v_ec_hash := f_hashWithSha384(bit2oct(v_enc_value));
        v_ec_hashed_id8 := f_HashedId8FromSha384(v_ec_hash);
      }
      log("f_generate_inner_at_request_with_wrong_parameters: v_ec_hash= ", v_ec_hash);
      log("f_generate_inner_at_request_with_wrong_parameters: v_ec_hashed_id8= ", v_ec_hashed_id8);
      if (p_alter_signer_digest == true) {
        v_ec_hashed_id8 := int2oct((f_getCurrentTimeUtc() * 1000), 8);
        log("f_generate_inner_at_request_with_wrong_parameters: Altered v_ec_hashed_id8= ", v_ec_hashed_id8);
      }
      
      // Generate 32 octets length secret key
      v_hmac_key := f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 12));
      log("f_generate_inner_at_request_with_wrong_parameters: v_hmac_key= ", v_hmac_key);

      // Generate tag based on the concatenation of verification keys & encryption keys
      if (f_generate_key_tag(p_public_key_compressed, p_compressed_key_mode, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_encoded_tag) == false) {
        log("f_generate_inner_at_request_with_wrong_parameters: Failed to generate Key tag");
        return false;
      }
      log("f_generate_inner_at_request_with_wrong_parameters: v_encoded_tag= ", v_encoded_tag);
      // Generate hmac key
      v_key_tag := substr(
                          fx_hmac_sha256( // TODO Rename and use a wrapper function
                                         v_hmac_key,
                                         v_encoded_tag
                                         ),
                          0,
                          16); // Leftmost 128 bits of the HMAC-SHA256 tag computed previously
      log("f_generate_inner_at_request_with_wrong_parameters: v_key_tag= ", v_key_tag);
      if (p_alter_hmac == true) {
        v_hmac_key[0] := 'aa'O;
        v_hmac_key[1] := 'bb'O;
        log("f_generate_inner_at_request_with_wrong_parameters: Altered key_tag= ", v_hmac_key);
      }
      
      // Build the SharedAtRequest
      if (not(ispresent(p_start))) {
        v_start := p_ec_certificate.toBeSigned.validityPeriod.start_;
      } else {
        v_start := valueof(p_start);
        log("f_generate_inner_at_request_with_wrong_parameters: Altered ValidityPeriod.start= ", v_start);
      }
      if (not(ispresent(p_duration))) {
        v_duration := p_ec_certificate.toBeSigned.validityPeriod.duration;
      } else {
        v_duration := valueof(p_duration);
        log("f_generate_inner_at_request_with_wrong_parameters: Altered ValidityPeriod.duration= ", v_duration);
      }
      p_inner_at_request.sharedAtRequest := valueof(
                                                    m_shared_at_request(
                                                                        p_ea_hashed_id8, // eaId identifies the EA certificate shared with EA entity
                                                                        v_key_tag, // Calculated keyTag
                                                                        valueof(
                                                                                m_certificate_subject_attributes(
YannGarcia's avatar
YannGarcia committed
                                                                                                                 v_appPermissions,
                                                                                                                 p_ec_certificate.toBeSigned.certRequestPermissions,
                                                                                                                 { none_ := NULL },//p_ec_certificate.toBeSigned.id,
                                                                                                                 m_validityPeriod(v_start, v_duration),
                                                                                                                 p_ec_certificate.toBeSigned.region,
                                                                                                                 p_ec_certificate.toBeSigned.assuranceLevel
                                                                                                                 ))) // Desired attributes
                                                    );
      
      // Calculate the hash of the SharedAtRequest
      v_hash_shared_at_request := f_hashWithSha256(bit2oct(encvalue(p_inner_at_request.sharedAtRequest)));
      log("f_generate_inner_at_request_with_wrong_parameters: v_hash_shared_at_request= ", v_hash_shared_at_request);
      
      // Build the ETsiTs103097Data-SignedExternalPayload
YannGarcia's avatar
YannGarcia committed
      if (ispresent(p_generation_time)) {
        v_tbs := m_toBeSignedData(
                                  m_signedDataPayload_ext(v_hash_shared_at_request), // Payload containing extDataHash
                                  m_headerInfo_inner_pki_request( // HeaderInfo
                                                                 -,
                                                                 valueof(p_generation_time) * 1000) //us
                                  );
        log("f_generate_inner_at_request_with_wrong_parameters: Altered generation time: v_tbs= ", v_tbs);
      } else {
        v_tbs := m_toBeSignedData(
                                  m_signedDataPayload_ext(v_hash_shared_at_request), // Payload containing extDataHash
                                  m_headerInfo_inner_pki_request( // HeaderInfo
                                                                 -,
                                                                 f_getCurrentTime() * 1000) //us
                                  );
        log("f_generate_inner_at_request_with_wrong_parameters: v_tbs= ", v_tbs);
      }
      // Signed ToBeSigned payload using the private key of EC certificate obtained from Enrolment request
      // In case of ITS-S privacy, v_signed_at_signature contained the data to be encrypted
      // TODO Simplify with f_signWithEcdsa
      if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1)) {
        v_hashId := sha384;
        v_tbs_signed := f_signWithEcdsaBrainpoolp384WithSha384(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
        v_signature := valueof(
                               m_signature_ecdsaBrainpoolP384r1(
                                                                m_ecdsaP384Signature(
                                                                                     m_eccP384CurvePoint_x_only(
                                                                                                                substr(v_tbs_signed, 0, 48)
                                                                                                                ),
                                                                                     substr(v_tbs_signed, 48, 48)
                                                                                     )
                                                                )
                                                        );
      } else {
        v_hashId := sha256;
        if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1)) {
          v_tbs_signed := f_signWithEcdsaBrainpoolp256WithSha256(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
          v_signature := valueof(
                                 m_signature_ecdsaBrainpoolP256r1(
                                                                  m_ecdsaP256Signature(
                                                                                       m_eccP256CurvePoint_x_only(
                                                                                                                  substr(v_tbs_signed, 0, 32)
                                                                                                                  ),
                                                                                       substr(v_tbs_signed, 32, 32)
                                                                                       )
                                                                  )
                                 );
        } else if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256)) {
          v_tbs_signed := f_signWithEcdsaNistp256WithSha256(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
          v_signature := valueof(
                                 m_signature_ecdsaNistP256(
                                                           m_ecdsaP256Signature(
                                                                                m_eccP256CurvePoint_x_only(
                                                                                                           substr(v_tbs_signed, 0, 32)
                                                                                                           ),
                                                                                substr(v_tbs_signed, 32, 32)
                                                                                )
                                                           )
                                 );
        } else {
          // Error
          log("f_generate_inner_at_request_with_wrong_parameters: Failed to process signature");
          return false;
        }
      }
      v_signed_at_signature := valueof(
                                       m_etsiTs103097Data_signed(
                                                                 m_signedData(
                                                                              v_hashId,
                                                                              v_tbs,
                                                                              m_signerIdentifier_digest(v_ec_hashed_id8), // Signer is the hasheId8 of the EC certificate obtained from Enrolment request
      log("f_generate_inner_at_request_with_wrong_parameters: v_signed_at_signature= ", v_signed_at_signature);
      
      if (PICS_ITS_S_WITH_PRIVACY) { // Build EtsiTs102097Data-Encrypted structure
        var octetstring v_public_enc_key;
        var integer v_compressed_mode;
        var Oct12 v_nonce;
        var Oct16 v_authentication_vector;
        var Oct16 v_aes_sym_key;
        var Oct16 v_encrypted_sym_key;
        var HashedId8 v_recipientId;
        var octetstring v_public_compressed_ephemeral_key;
        var integer v_public_compressed_ephemeral_mode;
        var octetstring v_enc_signed_ec_signature;
        var EncryptedDataEncryptionKey v_encrypted_data_encryption_key;
        
        // Use EA certificate for the encryption
YannGarcia's avatar
YannGarcia committed
        if (p_enc_algo == e_nist_p256) {
          if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0)) {
            v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0;
            v_compressed_mode := 0;
          } else if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1)) {
            v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1;
            v_compressed_mode := 1;
          } else {
            log("f_generate_inner_at_request_with_wrong_parameters: Wrong NistP256 encryption variant");
            return false;
          }
          v_enc_signed_ec_signature := f_encryptWithEciesNistp256WithSha256(bit2oct(encvalue(v_signed_at_signature)), v_public_enc_key, v_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, PICS_SEC_FIXED_KEYS);
          if (v_public_compressed_ephemeral_mode == 0) {
            v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key));
          } else {
            v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key));
          }
          v_encrypted_data_encryption_key := valueof(
                                                     m_encryptedDataEncryptionKey_eciesNistP256(
                                                                                                m_evciesP256EncryptedKey(
                                                                                                                         v_eccP256_curve_point,
                                                                                                                         v_encrypted_sym_key,
                                                                                                                         v_authentication_vector
                                                                                                                         )));
YannGarcia's avatar
YannGarcia committed
        } else if (p_enc_algo == e_brainpool_p256_r1) {
          if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0)) {
            v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0;
            v_compressed_mode := 0;
          } else if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1)) {
            v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1;
            v_compressed_mode := 1;
          } else {
            log("f_generate_inner_at_request_with_wrong_parameters: Wrong BrainpoolP256r1 encryption variant");
            return false;
          }
          v_enc_signed_ec_signature := f_encryptWithEciesBrainpoolp256WithSha256(bit2oct(encvalue(v_signed_at_signature)), v_public_enc_key, v_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, PICS_SEC_FIXED_KEYS);
          if (v_public_compressed_ephemeral_mode == 0) {
            v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key));
          } else {
            v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key));
          }
          v_encrypted_data_encryption_key := valueof(
                                                     m_encryptedDataEncryptionKey_eciesBrainpoolP256r1(
                                                                                                       m_evciesP256EncryptedKey(
                                                                                                                                v_eccP256_curve_point,
                                                                                                                                v_encrypted_sym_key,
                                                                                                                                v_authentication_vector
                                                                                                                                )));
        } else {
          log("f_generate_inner_at_request_with_wrong_parameters: Wrong encryption variant");
          return false;
        }
        log("f_generate_inner_at_request_with_wrong_parameters: v_encrypted_data_encryption_key= ", v_encrypted_data_encryption_key);
        v_recipientId := p_ea_hashed_id8; // RecipientId is the HashedId8 of the EA certificate
        log("f_generate_inner_at_request_with_wrong_parameters: v_recipientId= ", v_recipientId);
        // Fill Certificate template with the public compressed keys (canonical form)
        p_inner_at_request.ecSignature := valueof(
                                                  m_ec_signature(
                                                                 m_etsiTs103097Data_encrypted(
                                                                                              m_encryptedData(
                                                                                                              {
                                                                                                                m_recipientInfo_certRecipInfo(
                                                                                                                                              m_pKRecipientInfo(
                                                                                                                                                                v_recipientId,
                                                                                                                                                                
                                                                                                                                                                v_encrypted_data_encryption_key                                                                                                                                                            ))
                                                                                                                },
                                                                                                              m_SymmetricCiphertext_aes128ccm(
                                                                                                                                              m_aesCcmCiphertext(
                                                                                                                                                                 v_nonce,
                                                                                                                                                                 v_enc_signed_ec_signature
                                                                                                                                                                 )
                                                                                                                                              )
                                                                                                              )
                                                                                              )
                                                                 )
                                                  );
      } else { // Skip the encryption, alowed to be re-identified by the AA
        p_inner_at_request.ecSignature := valueof(m_ec_signature_ext_payload(v_signed_at_signature));
      }
      // Build the InnerAtRequest, EcSignature field is already set
      if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256)) {
        if (p_compressed_key_mode == 0) {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_x));
        } else {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_x));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaNistP256(v_eccP256_curve_point));
      } else if (ischosen(p_ec_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1)) {
        if (p_compressed_key_mode == 0) {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_key_x));
        } else {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_key_x));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP256r1(v_eccP256_curve_point));
      } else {
        var EccP384CurvePoint v_eccP384_curve_point;
        if (p_compressed_key_mode == 0) {
          v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_0(v_public_key_x));
        } else {
          v_eccP384_curve_point := valueof(m_eccP384CurvePoint_compressed_y_1(v_public_key_x));
        }
        v_public_verification_key := valueof(m_publicVerificationKey_ecdsaBrainpoolP384r1(v_eccP384_curve_point));
      }
      if (PX_INCLUDE_ENCRYPTION_KEYS) {
        if (p_compressed_enc_key_mode == 0) {
          v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_0(v_public_enc_key_x);
        } else {
          v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_1(v_public_enc_key_x);
        }
YannGarcia's avatar
YannGarcia committed
        if (p_enc_algo == e_nist_p256) {
          v_public_encryption_key := valueof(m_publicEncryptionKey_eciesNistP256(v_enc_eccP256_curve_point));
        } else {
          v_public_encryption_key := valueof(m_publicEncryptionKey_eciesBrainpoolP256r1(v_enc_eccP256_curve_point));
        }
        p_inner_at_request.publicKeys := valueof( // The freshly generated public verification & encrypition keys to be used for the requested AT certificate
                                                 m_publicKeys(
                                                              v_public_verification_key,
                                                              m_encryptionKey( // FIXME Encryption keys could be optional
                                                                              -,
                                                                              v_public_encryption_key
                                                                              )
                                                              )
                                                  );
      } else {
        p_inner_at_request.publicKeys := valueof( // The freshly generated public verification keys to be used for the requested AT certificate
                                                 m_publicKeys(
                                                              v_public_verification_key
                                                              )
                                                  );
      }
      p_inner_at_request.hmacKey := v_hmac_key;
      log("f_generate_inner_at_request_with_wrong_parameters: p_inner_at_request= ", p_inner_at_request);
      
      return true;
    } // End of function f_generate_inner_at_request_with_wrong_parameters
    
    function f_verify_inner_at_request_signed_for_pop(
                                                      in EtsiTs102941Data p_etsi_ts_102941_data,
                                                      out InnerAtRequest p_inner_at_request
                                                      ) return boolean {
      var bitstring v_msg_bit;

      log(">>> f_verify_inner_at_request_signed_for_pop: ", p_etsi_ts_102941_data);
      
      // 1. Decode content
      v_msg_bit := oct2bit(p_etsi_ts_102941_data.content.enrolmentRequest.content.signedData.tbsData.payload.data.content.unsecuredData);
      if (decvalue(v_msg_bit, p_inner_at_request) != 0) {
        log("f_verify_inner_at_request_signed_for_pop: Failed to decode InnerEcRequest");
        return false;
      } else {
        log("f_verify_inner_at_request_signed_for_pop: v_inner_at_request= ", p_inner_at_request);

        // 2. Verify the InnerEcRequestSignedForPop signature
        // TODO
      }
      
      return true;
    } // End of function f_verify_inner_at_request_signed_for_pop
    
    function f_generate_inner_at_response(
                                          in octetstring p_authorization_request_hash,
                                          in EtsiTs103097Certificate p_certificate,
                                          out InnerAtResponse p_authorization_response
                                          ) return boolean {
      // Local variables
      
      // Build the Proof of Possession InnerEcResponse
      p_authorization_response := valueof(
                                          m_innerAtResponse_ok(
                                                               substr(p_authorization_request_hash, 0, 16),
      
      return true;
    } // End of function f_generate_inner_at_response
    
  } // End of group inner_at_xxx
  
  group authorization_validation_xxx {
    
  } // End of group authorization_validation_xxx
  
  group awaiting_messages {
    
    function f_await_http_inner_ec_request_response(
Yann Garcia's avatar
Yann Garcia committed
                                                    out Oct32 p_private_key,
                                                    out Oct32 p_compressed_public_key,
                                                    out integer p_compressed_mode,
                                                    out InnerEcResponse p_inner_ec_response,
                                                    in boolean p_strict_checks := true
                                                    ) runs on ItsPkiHttp return boolean {
      var HeaderLines v_headers;
      var Oct32 v_request_hash;
      var Oct16 v_encrypted_sym_key;
      var Oct16 v_aes_sym_key;
      var HashedId8 v_aes_sym_key_hashed_id8;
      var Oct16 v_authentication_vector;
      var Oct12 v_nonce;
      var octetstring v_salt;
      var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
      var EtsiTs102941Data v_etsi_ts_102941_data;
      var HttpMessage v_response;
      log(">>> f_await_http_inner_ec_request_response: p_strict_checks=", p_strict_checks);
      
      f_http_build_inner_ec_request(p_private_key, p_compressed_public_key, p_compressed_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, v_salt, v_ieee1609dot2_signed_and_encrypted_data, v_request_hash);
      v_aes_sym_key_hashed_id8 := f_HashedId8FromSha256(f_hashWithSha256('80'O & v_aes_sym_key)); // Used to macth the response
      f_init_default_headers_list(-, "inner_ec_request", v_headers);
Yann Garcia's avatar
Yann Garcia committed
      f_http_send(
                  v_headers, 
                  m_http_request(
                                 m_http_request_post(
                                                     PICS_HTTP_POST_URI_EC,
                                                     v_headers,
                                                     m_http_message_body_binary(
                                                                                m_binary_body_ieee1609dot2_data(
                                                                                                                v_ieee1609dot2_signed_and_encrypted_data
                                                                                                                )))));
      tc_ac.start;
      alt {
        [] a_await_ec_http_request_from_iut(
                                            mw_http_response(
                                                             mw_http_response_ok(
                                                                                 mw_http_message_body_binary(
                                                                                                             mw_binary_body_ieee1609dot2_data(
                                                                                                                                              mw_enrolmentResponseMessage(
                                                                                                                                                                          mw_encryptedData(
                                                                                                                                                                                           { *, mw_recipientInfo_pskRecipInfo(v_aes_sym_key_hashed_id8), * },
                                                                                                                                                                                           mw_SymmetricCiphertext_aes128ccm
                                                                                                                                                                                           )))))),
                                            v_response
                                            ) {
          tc_ac.stop;
          if (f_verify_pki_response_message(p_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, p_strict_checks, -, v_etsi_ts_102941_data) == false) {
            log("f_await_http_inner_ec_request_response: Failed to verify PKI message ***");
            if (p_strict_checks) {
              return false;
          log("f_await_http_inner_ec_request_response: Receive ", v_etsi_ts_102941_data, " ***");
          // Verify the received EC certificate
          log("f_await_http_inner_ec_request_response: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec)))), " ***"); // TODO In TITAN, this is the only way to get the unmatching in log
          if (match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec)))) == false) {
            log("f_await_http_inner_ec_request_response: Unexpected message received ***");
            if (p_strict_checks) {
              return false;
            }
          }
          if (ischosen(v_etsi_ts_102941_data.content.enrolmentResponse) and ispresent(v_etsi_ts_102941_data.content.enrolmentResponse.certificate)) {
            if (f_verify_ec_certificate(v_etsi_ts_102941_data.content.enrolmentResponse.certificate, vc_eaCertificate, p_compressed_public_key, p_compressed_mode) == false) {
              log("f_await_http_inner_ec_request_response: Cannot verify EC certificate signature ***");
              if (p_strict_checks) {
                return false;
            p_inner_ec_response := v_etsi_ts_102941_data.content.enrolmentResponse;
            log("f_await_http_inner_ec_request_response: Well-secured EA certificate received ***");
            log("p_inner_ec_response= ", p_inner_ec_response);
          } else {
            log("f_await_http_inner_ec_request_response: Invalid message received ***");
            return false;
        }
        [] tc_ac.timeout {
          log("f_await_http_inner_ec_request_response: Expected message not received ***");
        }
      } // End of 'alt' statement
      
      return true;
    } // End of function f_await_http_inner_ec_request_response
    
    function f_await_ec_request_send_response(
                                              out InnerEcResponse p_inner_ec_response
                                              ) runs on ItsPkiHttp return boolean {
      var HttpMessage v_request;
      var boolean v_result := false;
      
      log(">>> f_await_ec_request_send_response");
      
      tc_ac.start;
      alt {
        [] a_await_ec_http_request_from_iut(
                                            mw_http_request(
                                                            mw_http_request_post(
                                                                                 PICS_HTTP_POST_URI_EC,
                                                                                 -,
                                                                                 mw_http_message_body_binary(
                                                                                                             mw_binary_body_ieee1609dot2_data(
                                                                                                                                              mw_enrolmentRequestMessage(
                                                                                                                                                                         mw_encryptedData(
                                                                                                                                                                                          -,
                                                                                                                                                                                          mw_SymmetricCiphertext_aes128ccm
                                                                                                                                                                                          )))))),
                                            v_request
                                            ) {
          var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
          var EtsiTs102941Data v_etsi_ts_102941_data;
          var Oct16 v_request_hash;
          var Oct16 v_aes_enc_key;
          var InnerEcRequest v_inner_ec_request;
          var template (value) HttpMessage v_response;
          var HeaderLines v_headers;
          
          tc_ac.stop;
          
          f_init_default_headers_list(-, "inner_ec_response", v_headers);
          
YannGarcia's avatar
YannGarcia committed
          if (f_verify_pki_request_message(vc_eaPrivateEncKey, vc_eaWholeHash/*salt*/, ''O, v_request.request.body.binary_body.ieee1609dot2_data, false, v_request_hash, v_etsi_ts_102941_data, v_aes_enc_key) == false) { // Cannot decrypt the message
            log("f_await_ec_request_send_response: Failed to verify PKI message ***");
            // Send error message
            v_response := m_http_response(m_http_response_ko(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), v_headers, 400, "Bad request")); // Initialize v_reponse with an error message
          } else {
            log("f_await_ec_request_send_response: Receive ", v_etsi_ts_102941_data, " ***");
            if (f_verify_inner_ec_request_signed_for_pop(v_etsi_ts_102941_data, v_inner_ec_request) == false) {
              log("f_await_ec_request_send_response: Failed to verify PKI message ***");
              // Send error message