LibItsPki_Functions.ttcn 325 KB
Newer Older
                                                                              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,
Yann Garcia's avatar
Yann Garcia committed
                                                      in EtsiTs103097Certificate p_ec_certificate,
                                                      out InnerAtRequest p_inner_at_request
                                                      ) return boolean {
      var bitstring v_msg_bit;

Yann Garcia's avatar
Yann Garcia committed
      log(">>> f_verify_inner_at_request_signed_for_pop: p_etsi_ts_102941_data=", p_etsi_ts_102941_data);
      log(">>> f_verify_inner_at_request_signed_for_pop: p_ec_certificate=", p_ec_certificate);
Yann Garcia's avatar
Yann Garcia committed
      // 1. Extract content
      p_inner_at_request := p_etsi_ts_102941_data.content.authorizationRequest;

        // 2. Verify the InnerEcRequestSignedForPop signature
        // TODO
      
Yann Garcia's avatar
Yann Garcia committed
      log("<<< f_verify_inner_at_request_signed_for_pop: ", p_inner_at_request);
      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 dc {

    function f_build_dc_ctl(
                            in charstring p_ea_certificate_id,
                            in charstring p_aa_certificate_id,
                            in charstring p_rca_certificate_id,
                            out ToBeSignedRcaCtl p_to_be_signed_rca_ctl
                            ) {
      // Local variables
      var EtsiTs103097Certificate v_ea_certificate;
      var EtsiTs103097Certificate v_aa_certificate;
      var EtsiTs103097Certificate v_rca_certificate;
      var CtlCommands v_ctl_commands;
      var ToBeSignedRcaCtl v_to_be_signed_rca_ctl;
      log(">>> f_build_dc_ctl");

      // Load certificates
      f_readCertificate(p_ea_certificate_id, v_ea_certificate);
      f_readCertificate(p_aa_certificate_id, v_aa_certificate);
      f_readCertificate(p_rca_certificate_id, v_rca_certificate);
      // Create ctrlCommnand list
      v_ctl_commands := {
        { add := { rca := valueof(m_root_ca_entry(v_rca_certificate)) } },
        { add := { aa := valueof(m_aa_entry(v_aa_certificate, "http://www.etsi.org")) } },
        { add := { ea := valueof(m_ea_entry(v_ea_certificate, "http://www.etsi.org")) } }
      };
      log("f_build_dc_ctl: v_ctl_commands= ", v_ctl_commands);
      // Build the main data structure
      p_to_be_signed_rca_ctl := valueof(m_to_be_signed_rca_full_ctl(1000, 1, v_ctl_commands));

      log("<<< f_build_dc_ctl: p_to_be_signed_rca_ctl= ", p_to_be_signed_rca_ctl);
    } // End of function f_build_dc_ctl

    function f_sign_dc_ctl(
                           in charstring p_issuer_certificate_id,
                           in ToBeSignedRcaCtl p_to_be_signed_rca_ctl,
                           out Ieee1609Dot2Data p_ieee_1609Dot2_signed_data
                           ) {
      // Local variables
      var EtsiTs103097Certificate v_certificate;
      var EtsiTs102941Data v_etsi_ts_102941_data;
      var octetstring v_pki_message;
      var ToBeSignedData v_tbs;
      var octetstring v_private_key;
      var octetstring v_issuer;
      var bitstring v_tbs_encoded;
      var octetstring v_sig;
      var Signature v_signature;

      log(">>> f_sign_dc_ctl");

      f_readSigningKey(p_issuer_certificate_id, v_private_key);
      f_getCertificateHash(p_issuer_certificate_id, v_issuer);

      // Encode the main data structure
      v_etsi_ts_102941_data := valueof(m_etsiTs102941Data_to_be_signed_rca_ctl(p_to_be_signed_rca_ctl));
      v_pki_message := bit2oct(encvalue(v_etsi_ts_102941_data));
      // Signed the encoded PKI message
      v_tbs := valueof(
                       m_toBeSignedData(
                                        m_signedDataPayload(
                                                            m_etsiTs103097Data_unsecured(v_pki_message)
                                                            ),
                                        m_headerInfo_inner_pki_response(-, (f_getCurrentTime() * 1000)/*us*/)
                                        )
                       );
      v_tbs_encoded := encvalue(v_tbs);
      // Sign the certificate
      v_sig := f_signWithEcdsa(bit2oct(v_tbs_encoded), v_issuer, v_private_key);
      if ((PX_VE_ALG == e_nist_p256) or (PX_VE_ALG == e_brainpool_p256_r1)) {
        v_signature := valueof(
                               m_signature_ecdsaNistP256(
                                                         m_ecdsaP256Signature(
                                                                              m_eccP256CurvePoint_x_only(
                                                                                                         substr(v_sig, 0, 32)
                                                                                                         ),
                                                                              substr(v_sig, 32, 32)
                                                                              )
                                                         ));
        p_ieee_1609Dot2_signed_data := valueof(
                                               m_etsiTs103097Data_signed(
                                                                         m_signedData(
                                                                                      sha256,
                                                                                      v_tbs,
                                                                                      m_signerIdentifier_digest(v_issuer),
                                                                                      v_signature
                                                                                      )
                                                                         )
                                               );
      } else if (PX_VE_ALG == e_brainpool_p384_r1) {
        v_signature := valueof(
                               m_signature_ecdsaBrainpoolP384r1(
                                                                m_ecdsaP384Signature(
                                                                                     m_eccP384CurvePoint_x_only(
                                                                                                                substr(v_sig, 0, 48)
                                                                                                                ),
                                                                                     substr(v_sig, 48, 48)
                                                                                     )
                                                                ));
        p_ieee_1609Dot2_signed_data := valueof(
                                               m_etsiTs103097Data_signed(
                                                                         m_signedData(
                                                                                      sha384,
                                                                                      v_tbs,
                                                                                      m_signerIdentifier_digest(v_issuer),
                                                                                      v_signature
                                                                                      )
                                                                         )
                                               );
      }
      log("<<< f_sign_dc_ctl: p_ieee_1609Dot2_signed_data= ", p_ieee_1609Dot2_signed_data);
    } // End of function f_sign_dc_ctl

  } // End of group dc

YannGarcia's avatar
YannGarcia committed
  group rca {
YannGarcia's avatar
YannGarcia committed
    function f_verify_rca_ctl_response_message(
                                               in EtsiTs103097Data p_etsi_ts_103097_signed_data,
YannGarcia's avatar
YannGarcia committed
                                               in boolean p_check_security := true,
                                               out ToBeSignedRcaCtl p_to_be_signed_rca_ctl
                                               ) return boolean {
YannGarcia's avatar
YannGarcia committed
      var bitstring v_etsi_ts_102941_data_msg;
      var bitstring v_tbs;
      var Certificate v_certificate;
      var charstring v_certificate_id;
      var octetstring v_issuer;
YannGarcia's avatar
YannGarcia committed
      var EtsiTs102941Data v_etsi_ts_102941_data;

      log(">>> f_verify_rca_ctl_response_message: p_etsi_ts_103097_signed_data= ", p_etsi_ts_103097_signed_data);
YannGarcia's avatar
YannGarcia committed

      // 1. Verify signature
      log("f_verify_rca_ctl_response_message: p_etsi_ts_103097_signed_data.content.signedData.tbsData= ", p_etsi_ts_103097_signed_data.content.signedData.tbsData);
      v_tbs := encvalue(p_etsi_ts_103097_signed_data.content.signedData.tbsData);
      if (f_getCertificateFromDigest(p_etsi_ts_103097_signed_data.content.signedData.signer.digest, v_certificate, v_certificate_id) == false) {
        log("f_verify_rca_ctl_response_message: Failed to retrieve certificate from ", p_etsi_ts_103097_signed_data.content.signedData.signer.digest);
YannGarcia's avatar
YannGarcia committed
        if (p_check_security == true) {
          return false;
        }
      }
      f_getCertificateHash(v_certificate_id, v_issuer);
      if (f_verifyEcdsa(bit2oct(v_tbs), v_issuer, p_etsi_ts_103097_signed_data.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) {
        log("f_verify_rca_ctl_response_message: Failed to verify signature");
YannGarcia's avatar
YannGarcia committed
        if (p_check_security == true) {
          return false;
        }
      }
      v_etsi_ts_102941_data_msg := oct2bit(p_etsi_ts_103097_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData);
YannGarcia's avatar
YannGarcia committed
      if (decvalue(v_etsi_ts_102941_data_msg, v_etsi_ts_102941_data) != 0) {
YannGarcia's avatar
YannGarcia committed
        log("f_verify_rca_ctl_response_message: Failed to decode EtsiTs102941Data");
YannGarcia's avatar
YannGarcia committed
        return false;
      } else {
YannGarcia's avatar
YannGarcia committed
        log("f_verify_rca_ctl_response_message: v_etsi_ts_102941_data= ", v_etsi_ts_102941_data);
YannGarcia's avatar
YannGarcia committed
        log("f_verify_pki_response_message: RcaCertificateTrustListMessage matching= ", match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_rca_ctl));
        if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_rca_ctl) == false) {
YannGarcia's avatar
YannGarcia committed
          log("f_verify_rca_ctl_response_message: Failed to decode certificateTrustListRca");
YannGarcia's avatar
YannGarcia committed
          return false;
        } else {
          var Time32 v_time := (f_getCurrentTime()/* - 1072915200000*/) / 1000;
YannGarcia's avatar
YannGarcia committed
          p_to_be_signed_rca_ctl := v_etsi_ts_102941_data.content.certificateTrustListRca;
YannGarcia's avatar
YannGarcia committed
          log("f_verify_rca_ctl_response_message: p_to_be_signed_rca_ctl= ", p_to_be_signed_rca_ctl);
          if (p_to_be_signed_rca_ctl.nextUpdate <= v_time) {
            log("f_verify_rca_ctl_response_message: Invalid nextUpdate value: compared values=", p_to_be_signed_rca_ctl.nextUpdate, "/", v_time);
YannGarcia's avatar
YannGarcia committed
            return false;
          }
          // TODO Verify RCA certificate & signature
YannGarcia's avatar
YannGarcia committed
        }
      }

      return true;
    }

    function f_verify_rca_crl_response_message(
                                               in EtsiTs103097Data p_etsi_ts_103097_signed_data,
YannGarcia's avatar
YannGarcia committed
                                               in boolean p_check_security := true,
                                               out ToBeSignedCrl p_to_be_signed_crl
                                               ) return boolean {
      var bitstring v_etsi_ts_102941_data_msg;
      var bitstring v_tbs;
      var Certificate v_certificate;
      var charstring v_certificate_id;
      var octetstring v_issuer;
YannGarcia's avatar
YannGarcia committed
      var EtsiTs102941Data v_etsi_ts_102941_data;

      log(">>> f_verify_rca_crl_response_message: p_etsi_ts_103097_signed_data= ", p_etsi_ts_103097_signed_data);
YannGarcia's avatar
YannGarcia committed

      // 1. Verify signature
      log("f_verify_rca_crl_response_message: p_etsi_ts_103097_signed_data.content.signedData.tbsData= ", p_etsi_ts_103097_signed_data.content.signedData.tbsData);
      v_tbs := encvalue(p_etsi_ts_103097_signed_data.content.signedData.tbsData);
      if (f_getCertificateFromDigest(p_etsi_ts_103097_signed_data.content.signedData.signer.digest, v_certificate, v_certificate_id) == false) {
        log("f_verify_rca_crl_response_message: Failed to retrieve certificate from ", p_etsi_ts_103097_signed_data.content.signedData.signer.digest);
YannGarcia's avatar
YannGarcia committed
        if (p_check_security == true) {
          return false;
        }
      }
      f_getCertificateHash(v_certificate_id, v_issuer);
      if (f_verifyEcdsa(bit2oct(v_tbs), v_issuer, p_etsi_ts_103097_signed_data.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) {
        log("f_verify_rca_crl_response_message: Failed to verify signature");
YannGarcia's avatar
YannGarcia committed
        if (p_check_security == true) {
          return false;
        }
      }
      v_etsi_ts_102941_data_msg := oct2bit(p_etsi_ts_103097_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData);
YannGarcia's avatar
YannGarcia committed
      if (decvalue(v_etsi_ts_102941_data_msg, v_etsi_ts_102941_data) != 0) {
        log("f_verify_rca_crl_response_message: Failed to decode EtsiTs102941Data");
        return false;
      } else {
        log("f_verify_rca_crl_response_message: v_etsi_ts_102941_data= ", v_etsi_ts_102941_data);
        log("f_verify_pki_response_message: CertificateRevocationList matching= ", match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_crl));
        if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_crl) == false) {
          log("f_verify_rca_crl_response_message: Failed to decode certificateRevocationList");
          return false;
        } else {
          var Time32 v_time := (f_getCurrentTime()/* - 1072915200000*/) / 1000;
YannGarcia's avatar
YannGarcia committed
          p_to_be_signed_crl := v_etsi_ts_102941_data.content.certificateRevocationList;
          log("f_verify_rca_crl_response_message: p_to_be_signed_crl= ", p_to_be_signed_crl);
          if (p_to_be_signed_crl.thisUpdate >= v_time) {
            log("f_verify_rca_crl_response_message: Invalid thisUpdate value");
            return false;
          }
          if (p_to_be_signed_crl.nextUpdate <= v_time) {
            log("f_verify_rca_crl_response_message: Invalid nextUpdate value");
            return false;
          }
Yann Garcia's avatar
Yann Garcia committed
          // TODO Verify RCA certificate & signature
YannGarcia's avatar
YannGarcia committed
        }
      }

      return true;
    }

    function f_verify_full_ctl(
                               in ToBeSignedRcaCtl p_to_be_signed_rca_ctl
                               ) return boolean {
      log(">>> f_verify_full_ctl: p_to_be_signed_rca_ctl= ", p_to_be_signed_rca_ctl);

      // 1. Check mandatory fields
      log("f_verify_full_ctl matching= ", match(p_to_be_signed_rca_ctl, mw_to_be_signed_rca_full_ctl));
      if (match(p_to_be_signed_rca_ctl, mw_to_be_signed_rca_full_ctl) == false) {
        return false;
      }

      log("f_verify_full_ctl: ctlCommands length: ", lengthof(p_to_be_signed_rca_ctl.ctlCommands));
      for (var integer v_i := 0;  v_i < lengthof(p_to_be_signed_rca_ctl.ctlCommands); v_i := v_i + 1) {
        var CtlCommand v_ctl_command := p_to_be_signed_rca_ctl.ctlCommands[v_i];

        if (ischosen(v_ctl_command.delete)) {
          log("f_verify_full_ctl: ctlCommands shall not contains 'delete' variant");
          return false;
        } else {
          if (f_verify_ctl_entry(v_ctl_command.add) == false) {
Yann Garcia's avatar
Yann Garcia committed
            log("f_verify_full_ctl: ctlCommands contains invalid entries");
YannGarcia's avatar
YannGarcia committed
            return false;
          }
        }
      } // End of 'for' statements
      
      return true;
    }

YannGarcia's avatar
YannGarcia committed
    function f_verify_full_crl(
                               in ToBeSignedCrl p_to_be_signed_crl
                               ) return boolean {
      log(">>> f_verify_full_crl: p_to_be_signed_crl= ", p_to_be_signed_crl);

      // 1. Check mandatory fields
      log("f_verify_full_crl matching= ", match(p_to_be_signed_crl, mw_to_be_signed_crl));
      if (match(p_to_be_signed_crl, mw_to_be_signed_crl) == false) {
        return false;
      }

      log("f_verify_full_crl: entries length: ", lengthof(p_to_be_signed_crl.entries));
      for (var integer v_i := 0;  v_i < lengthof(p_to_be_signed_crl.entries); v_i := v_i + 1) {
        var CrlEntry v_crl_entry := p_to_be_signed_crl.entries[v_i];

        log("f_verify_full_crl: crlEntry: v_crl_entry");
      } // End of 'for' statements
      
      return true;
    }

YannGarcia's avatar
YannGarcia committed
    function f_verify_full_ectl(
                               in ToBeSignedRcaCtl p_to_be_signed_tlm_ectl
                               ) return boolean {
      log(">>> f_verify_full_ectl: p_to_be_signed_tlm_ectl= ", p_to_be_signed_tlm_ectl);

      // 1. Check mandatory fields
      log("f_verify_full_ectl matching= ", match(p_to_be_signed_tlm_ectl, mw_to_be_signed_rca_full_ctl));
      if (match(p_to_be_signed_tlm_ectl, mw_to_be_signed_rca_full_ctl) == false) {
        return false;
      }

      log("f_verify_full_ectl: ctlCommands length: ", lengthof(p_to_be_signed_tlm_ectl.ctlCommands));
      for (var integer v_i := 0;  v_i < lengthof(p_to_be_signed_tlm_ectl.ctlCommands); v_i := v_i + 1) {
        var CtlCommand v_ectl_command := p_to_be_signed_tlm_ectl.ctlCommands[v_i];

        if (ischosen(v_ectl_command.delete)) {
          log("f_verify_full_ectl: ctlCommands shall not contains 'delete' variant");
          return false;
        } else {
          if (f_verify_ectl_entry(v_ectl_command.add) == false) {
Yann Garcia's avatar
Yann Garcia committed
            log("f_verify_full_ectl: ctlCommands contains invalid entries");
YannGarcia's avatar
YannGarcia committed
            return false;
          }
        }
      } // End of 'for' statements
Yann Garcia's avatar
Yann Garcia committed

YannGarcia's avatar
YannGarcia committed
      return true;
    }

YannGarcia's avatar
YannGarcia committed
    function f_verify_ctl_entry(
                                in CtlEntry p_ctl_entry
                                ) return boolean {
Yann Garcia's avatar
Yann Garcia committed
      log(">>> f_verify_ctl_entry: p_ctl_entry=", p_ctl_entry);

YannGarcia's avatar
YannGarcia committed
      if (ischosen(p_ctl_entry.rca)) {
        if (match(p_ctl_entry.rca, mw_root_ca_entry(mw_etsiTs103097Certificate)) == false) {
          return false;
Yann Garcia's avatar
Yann Garcia committed
        } else {
          // TODO Verify RCA certificate & signature
YannGarcia's avatar
YannGarcia committed
        }
     } else if (ischosen(p_ctl_entry.ea)) {
        if (match(p_ctl_entry.ea, mw_ea_entry(mw_etsiTs103097Certificate)) == false) {
          return false;
Yann Garcia's avatar
Yann Garcia committed
        } else {
          // TODO Verify RCA certificate & signature
YannGarcia's avatar
YannGarcia committed
        }
      } else if (ischosen(p_ctl_entry.aa)) {
        if (match(p_ctl_entry.aa, mw_aa_entry(mw_etsiTs103097Certificate)) == false) {
          return false;
Yann Garcia's avatar
Yann Garcia committed
        } else {
          // TODO Verify RCA certificate & signature
YannGarcia's avatar
YannGarcia committed
        }
      } else if (ischosen(p_ctl_entry.dc)) {
        if (match(p_ctl_entry.dc, mw_dc_entry) == false) {
          return false;
Yann Garcia's avatar
Yann Garcia committed
        } else {
          // TODO Verify RCA certificate & signature
YannGarcia's avatar
YannGarcia committed
        }
YannGarcia's avatar
YannGarcia committed
      } else {
        return false;
      }

      return true;
    }
Yann Garcia's avatar
Yann Garcia committed

YannGarcia's avatar
YannGarcia committed
    function f_verify_ectl_entry(
                                 in CtlEntry p_ctl_entry
                                 ) return boolean {
Yann Garcia's avatar
Yann Garcia committed
      log(">>> f_verify_ectl_entry: p_ctl_entry=", p_ctl_entry);

YannGarcia's avatar
YannGarcia committed
      if (ischosen(p_ctl_entry.tlm)) {
YannGarcia's avatar
YannGarcia committed
        if (match(p_ctl_entry.tlm, mw_tlm_entry(mw_etsiTs103097Certificate)) == false) {
          return false;
YannGarcia's avatar
YannGarcia committed
        } else {
          // TODO Verify RCA certificate & signature
YannGarcia's avatar
YannGarcia committed
        }
      } else if (ischosen(p_ctl_entry.dc)) {
        if (match(p_ctl_entry.dc, mw_dc_entry) == false) {
          return false;
        } else {
          // TODO Verify RCA certificate & signature
        }
Yann Garcia's avatar
Yann Garcia committed
      } else if (ischosen(p_ctl_entry.rca)) {
        if (match(p_ctl_entry.rca, mw_root_ca_entry(mw_etsiTs103097Certificate)) == false) {
          return false;
        } else {
          // TODO Verify RCA certificate & signature
        }
YannGarcia's avatar
YannGarcia committed
      } else {
        return false;
      }

      return true;
    }

    /**
     * @desc this function is used to retrieve the root certificate from SubCA entity
     * @param p_certificate The root certificate
     * @return 0 on success, -1 otherwise
     */
    external function fx_get_root_ca_certificate(
                                                 in charstring p_iut_certificate := "CERT_IUT_A_RCA",//"CERT_IUT_A_CA",
                                                 in boolean p_explicit_type := false,
                                                 out octetstring p_certificate
                                                 ) return integer;

    function f_get_root_ca_certificate(
                                       in charstring p_iut_certificate := "CERT_IUT_A_CA",
                                       in boolean p_explicit_type := false,
                                       out Certificate p_certificate
                                       ) return integer {
      var octetstring v_os;
      var bitstring v_msg_bit;

      log(">>> f_get_root_ca_certificate");

      // Get root certificate
      if (fx_get_root_ca_certificate(p_iut_certificate, p_explicit_type, v_os) != 0) {
        log("f_get_root_ca_certificate: fail to get certificate");
        return -1;
      }
      log("f_get_root_ca_certificate: v_os=", v_os);
      // Decode it
      v_msg_bit := oct2bit(v_os);
      if (decvalue(v_msg_bit, p_certificate) != 0) {
        log("f_get_root_ca_certificate: fail to decode certificate");
        return -1;
      }
      log("<<< f_get_root_ca_certificate: ", p_certificate);
      return 0;
    }

    function f_verify_rca_certificate(
                                      in charstring p_authorized_certificate := "CERT_IUT_A_RCA",//"CERT_IUT_A_RCA",
                                      in Certificate p_certificate,
                                      in boolean p_check_implicit := false,
                                      in boolean p_check_reconstruction_value := false,
                                      in boolean p_check_no_signature := false,
                                      in boolean p_check_region_restriction := false,
                                      in boolean p_check_signature_content := false,
                                      in boolean p_check_app_permissions := false,
                                      in boolean p_check_app_ssps := false,
                                      in boolean p_check_app_validity_period := false
                                      ) return boolean {
      var CertificateType v_type_ := explicit;
      var template Signature v_signature_ := ?;
      var template IssuerIdentifier v_issuer := ?;
      var template PublicVerificationKey v_public_verification_key := ?;

      log(">>> f_verify_rca_certificate: p_authorized_certificate= ", p_authorized_certificate);
      log(">>> f_verify_rca_certificate: p_certificate= ", p_certificate);

      if (p_check_implicit == true) {
        v_type_ := implicit;
      }
      if (p_check_no_signature == true) {
        v_signature_ := omit;
      }
      if (match(p_certificate, mw_etsiTs103097Certificate(-, -, v_signature_, v_type_)) == false) {
        log("f_verify_rca_certificate: version/explicit mismatch");
        return false;
      }
      if (p_check_reconstruction_value == false) {
        if (match(p_certificate, mw_etsiTs103097Certificate(
                                                            -,
                                                            mw_toBeSignedCertificate_ca(
                                                                                        (mw_certificateId_none, mw_certificateId_name),
                                                                                        -,
                                                                                        -,
                                                                                        mw_verificationKeyIndicator_verificationKey
                                                                                        ),
                                                            v_signature_
                                                            )) == false) {
          log("f_verify_rca_certificate: verificationKey mismatch");
          return false;
        }
        if (p_check_signature_content) {
          var template PublicVerificationKey v_publicVerificationKey;
          
          if (PICS_SEC_SHA256) {
            v_signature_ := mw_signature_ecdsaNistP256;
            v_issuer := (mw_issuerIdentifier_self(sha256), mw_issuerIdentifier_sha256AndDigest);
            v_public_verification_key := mw_publicVerificationKey_ecdsaNistP256;
          } else if (PICS_SEC_BRAINPOOL_P256R1) {
            v_signature_ := mw_signature_ecdsaBrainpoolP256r1;
            v_issuer := (mw_issuerIdentifier_self(sha256), mw_issuerIdentifier_sha256AndDigest);
            v_public_verification_key := mw_publicVerificationKey_ecdsaBrainpoolP256r1;
          } else if (PICS_SEC_BRAINPOOL_P384R1) {
            v_signature_ := mw_signature_ecdsaBrainpoolP384r1;
            v_issuer := (mw_issuerIdentifier_self(sha384), mw_issuerIdentifier_sha384AndDigest);
            v_public_verification_key := mw_publicVerificationKey_ecdsaBrainpoolP384r1;
          }
          if (match(p_certificate, mw_etsiTs103097Certificate(
                                                              v_issuer,
                                                              mw_toBeSignedCertificate_ca(
                                                                                          (mw_certificateId_none, mw_certificateId_name),
                                                                                          -,
                                                                                          -,
                                                                                          mw_verificationKeyIndicator_verificationKey(v_public_verification_key),
                                                                                          -, -, -, -,
                                                                                          -//mw_encryptionKey
                                                                                          ),
                                                              v_signature_
                                                              )) == false) {
            log("f_verify_rca_certificate: signature mismatch");
            return false;
          }
          // Verify Signature
          if (ischosen(p_certificate.issuer.self_)) {
            v_publicVerificationKey := p_certificate.toBeSigned.verifyKeyIndicator.verificationKey;
          } else {
            var HashedId8 v_digest;
            var Certificate v_authorized_certificate;
            var charstring v_cert;
            
            if (ischosen(p_certificate.issuer.sha256AndDigest)) {
              v_digest := p_certificate.issuer.sha256AndDigest;
            } else if (ischosen(p_certificate.issuer.sha384AndDigest)) {
              v_digest := p_certificate.issuer.sha384AndDigest;
            } else {
              log("f_verify_rca_certificate: Invalid certificate issuer ", p_certificate.issuer);
              return false;
            }
            if (f_getCertificateFromDigest(v_digest, v_authorized_certificate, v_cert) == false) {
              log("f_verify_rca_certificate: Fail to load p_authorized_certificate");
              return false;
            }
            v_publicVerificationKey := v_authorized_certificate.toBeSigned.verifyKeyIndicator.verificationKey
          }
          log("f_verify_rca_certificate: v_publicVerificationKey= ", v_publicVerificationKey);
          if (f_verifyCertificateSignatureWithPublicKey(p_certificate, v_publicVerificationKey) == false) {
            log("f_verify_rca_certificate: signature not verified");
            return false;
          }
        }
      } else {
        if (match(p_certificate, mw_etsiTs103097Certificate(
                                                            -,
                                                            mw_toBeSignedCertificate_ca(
                                                                                        (mw_certificateId_none, mw_certificateId_name),
                                                                                        -,
                                                                                        -,
                                                                                        mw_verificationKeyIndicator_reconstructionValue
                                                                                        ),
                                                            v_signature_
                                                            )) == false) {
          log("f_verify_rca_certificate: verificationKey mismatch");
          return false;
        }
        // TODO Verify Signature
      }

      if (p_check_region_restriction == true) {
        var Certificate v_authorized_certificate;
        var template GeographicRegion v_geographic_region := ?;

        if (f_readCertificate(p_authorized_certificate, v_authorized_certificate) == false) {
          log("f_verify_rca_certificate: Fail to load p_authorized_certificate");
          return false;
        }
        log("f_verify_rca_certificate: v_authorized_certificate=", v_authorized_certificate);

        if (PICS_SEC_CIRCULAR_REGION == true) {
          v_geographic_region := mw_geographicRegion_circle;
        } else if (PICS_SEC_RECTANGULAR_REGION == true) {
          v_geographic_region := mw_geographicRegion_rectangular;
        } else if (PICS_SEC_POLYGONAL_REGION == true) {
          v_geographic_region := mw_geographicRegion_polygonal;
        } else if (PICS_SEC_IDENTIFIED_REGION == true) {
        v_geographic_region := mw_geographicRegion_identified(
                                                              {
                                                                (mw_identifiedRegion_country_only, mw_identifiedRegion_country_and_region)
                                                                }
                                                              );
        }
        if (match(p_certificate, mw_etsiTs103097Certificate(
                                                            -,
                                                            mw_toBeSignedCertificate_ca(
                                                                                        -,
                                                                                        -,
                                                                                        -,
                                                                                        -,
                                                                                        -,
                                                                                        -,
                                                                                        v_geographic_region
                                                                                        )
                                                            )) == false) {
          log("f_verify_rca_certificate: Geographical region mismatch");
          return false;
        }
        // Check interception of area
        if (f_checkRegionValidityRestiction(v_authorized_certificate, p_certificate) == false) {
          log("f_verify_rca_certificate: Geographical region intersection mismatch");
          return false;
        }
      }
      // Check appPermissions
      if (p_check_app_permissions == true) {
        var integer v_idx, v_jdx;
        var charstring v_psid := ""; // 'psid' currently processed
        var charstring v_psidsFound := ";"; // Used to build the list of the 'psid' already processed
        var template charstring m_found_pattern; // Used in regex to verify that 'psid' was not found before
        var Certificate v_authorized_certificate;

        if (f_readCertificate(p_authorized_certificate, v_authorized_certificate) == false) {
          log("f_verify_rca_certificate: Fail to load p_authorized_certificate");
          return false;
        }
        log("f_verify_rca_certificate: v_authorized_certificate=", v_authorized_certificate);
        if (match(v_authorized_certificate.toBeSigned.certIssuePermissions, { mw_psidGroupPermissions }) == false) {
          log("f_verify_rca_certificate: eeType mismatch");
          return false;
        }
        for (v_idx := 0; v_idx < lengthof(p_certificate.toBeSigned.appPermissions); v_idx := v_idx + 1) {
          log("f_verify_rca_certificate: Processing ", p_certificate.toBeSigned.appPermissions[v_idx]);
          if (match(p_certificate.toBeSigned.appPermissions[v_idx], mw_appPermissions) == false) {
            log("f_verify_rca_certificate: PsidSsp mismatch");
            return false;
          }
          // Check uniqueness of PSIDs
          v_psid := int2str(p_certificate.toBeSigned.appPermissions[v_idx].psid);
          m_found_pattern := pattern "*({v_psid})*";
          if (regexp(v_psidsFound, m_found_pattern, 0) == v_psid) {
            log("f_verify_rca_certificate: Psid uniqueness is not verified");
            return false; // v_psid exist at least 2 times, uniqueness is not verified
          }
          // v_psid non found, add it into the built list
          v_psidsFound := v_psidsFound & v_psid & ";";
          // Check that 'psid' is in the certIssuePermissions component in the issuing certificate
          if (match(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions, mw_subjectPermissions_explicit) == false) {
            for (v_jdx := 0; v_jdx < lengthof(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit); v_jdx := v_jdx + 1) {
              if (int2str(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit[v_jdx].psid) == v_psid) {
                break;
              }
            } // End of 'for'statement
            if (v_jdx == lengthof(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit)) {
              log("f_verify_rca_certificate: Psid is not in the list of the issuing certificate");
              return false;
            }
          }
        } // End of 'for'statement
      }

      if (p_check_app_ssps == true) {
        var integer v_idx, v_jdx;
        var Certificate v_authorized_certificate;

        if (f_readCertificate(p_authorized_certificate, v_authorized_certificate) == false) {
          log("f_verify_rca_certificate: Fail to load p_authorized_certificate");
          return false;
        }
        log("f_verify_rca_certificate: v_authorized_certificate=", v_authorized_certificate);
        for (v_idx := 0; v_idx < lengthof(p_certificate.toBeSigned.appPermissions); v_idx := v_idx + 1) {
          log("f_verify_rca_certificate: Processing ", p_certificate.toBeSigned.appPermissions[v_idx]);
          if (match(p_certificate.toBeSigned.appPermissions[v_idx], mw_appPermissions(-, ?)) == false) {
            log("f_verify_rca_certificate: appPermissions mismatch");
            return false;
          }
          // Check that 'ssp' is in the certIssuePermissions component in the issuing certificate
          for (v_jdx := 0; v_jdx < lengthof(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit); v_jdx := v_jdx + 1) {
            log("f_verify_rca_certificate: compare psid ", v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit[v_jdx].psid, " - ", p_certificate.toBeSigned.appPermissions[v_idx].psid);
            if (v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit[v_jdx].psid == p_certificate.toBeSigned.appPermissions[v_idx].psid) {
              break;
            }
          } // End of 'for'statement
          if (v_jdx == lengthof(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit)) {
            log("f_verify_rca_certificate: Psid is not in the list of the issuing certificate");
            return false;
          } else {
            var BitmapSsp v_ssp_ca := substr(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit[v_jdx].sspRange.bitmapSspRange.sspValue, 1, -1 + lengthof(v_authorized_certificate.toBeSigned.certIssuePermissions[0].subjectPermissions.explicit[v_jdx].sspRange.bitmapSspRange.sspValue));
            log("f_verify_rca_certificate: v_ssp_ca= ", v_ssp_ca, " - ssp= ", p_certificate.toBeSigned.appPermissions[v_idx].ssp.bitmapSsp);
            if (v_ssp_ca != p_certificate.toBeSigned.appPermissions[v_idx].ssp.bitmapSsp) {
              log("f_verify_rca_certificate: SSPs mismatch: CA");
              return false;
            }
          }
        } // End of 'for'statement
      }

      if (p_check_app_validity_period == true) {
        var integer v_idx, v_jdx;
        var Certificate v_authorized_certificate;
        var UInt32 v_duration, v_duration_ca;

        if (f_readCertificate(p_authorized_certificate, v_authorized_certificate) == false) {
          log("f_verify_rca_certificate: Fail to load p_authorized_certificate");
          return false;
        }
        log("f_verify_rca_certificate: v_authorized_certificate=", v_authorized_certificate);
        // Check start date (indicating X_START_VALIDITY ( X_START_VALIDITY >= X_START_VALIDITY_CA ))
        if (p_certificate.toBeSigned.validityPeriod.start_ < v_authorized_certificate.toBeSigned.validityPeriod.start_) {
          log("f_verify_rca_certificate: validityPeriod.start_ mismatch");
          return false;
        }
        // Check duration (value <= X_START_VALIDITY_CA + X_DURATION_CA - X_START_VALIDITY)
        v_duration := duration_to_uint32(p_certificate.toBeSigned.validityPeriod.duration);
        v_duration_ca := duration_to_uint32(v_authorized_certificate.toBeSigned.validityPeriod.duration);
        if (v_duration > (v_authorized_certificate.toBeSigned.validityPeriod.start_ + v_duration_ca - p_certificate.toBeSigned.validityPeriod.start_)) {
          log("f_verify_rca_certificate: validityPeriod.duration mismatch");
          return false;
        }
      }
YannGarcia's avatar
YannGarcia committed
      return true;
    }
Yann Garcia's avatar
Yann Garcia committed

    function duration_to_uint32(
                                in Duration p_duration
                                ) return UInt32 {
      if (ischosen(p_duration.microseconds)) {
        return p_duration.microseconds * 1000000;
      }
      else if (ischosen(p_duration.milliseconds)) {
        return p_duration.milliseconds * 1000;
      }
      else if (ischosen(p_duration.seconds)) {
        return p_duration.seconds;
      }
      else if (ischosen(p_duration.minutes)) {
        return p_duration.minutes * 60;
      }
      else if (ischosen(p_duration.hours)) {
        return p_duration.hours * 3600;
      }
      else if (ischosen(p_duration.sixtyHours)) {
        return p_duration.sixtyHours * 60 * 3600;
      }
      else if (ischosen(p_duration.sixtyHours)) {
        return p_duration.sixtyHours * 60 * 3600;
      }
      // No choice!
      return p_duration.years * 31536000; // One calendar common year has 365 days
    }

YannGarcia's avatar
YannGarcia committed
  } // End of group rca
Yann Garcia's avatar
Yann Garcia committed

  group tlm {

    function f_verify_tlm_ectl_response_message(
                                                in EtsiTs103097Data p_etsi_ts_103097_signed_data,
Yann Garcia's avatar
Yann Garcia committed
                                                in boolean p_check_security := true,
                                                out ToBeSignedTlmCtl p_to_be_signed_tlm_ectl
                                                ) return boolean {
      var bitstring v_etsi_ts_102941_data_msg;
      var bitstring v_tbs;
      var Certificate v_certificate;
      var boolean v_result;
      var EtsiTs102941Data v_etsi_ts_102941_data;

      log(">>> f_verify_tlm_ectl_response_message: p_etsi_ts_103097_signed_data= ", p_etsi_ts_103097_signed_data);
Yann Garcia's avatar
Yann Garcia committed

      // 1. Verify signature
      log("f_verify_tlm_ectl_response_message: p_etsi_ts_103097_signed_data.content.signedData.tbsData= ", p_etsi_ts_103097_signed_data.content.signedData.tbsData);
      v_tbs := encvalue(p_etsi_ts_103097_signed_data.content.signedData.tbsData);
      if (ischosen(p_etsi_ts_103097_signed_data.content.signedData.signer.certificate)) {
          v_certificate := p_etsi_ts_103097_signed_data.content.signedData.signer.certificate[0];
      } else {
          var charstring v_certificate_id;
          if (f_getCertificateFromDigest(p_etsi_ts_103097_signed_data.content.signedData.signer.digest, v_certificate, v_certificate_id) == false) {
            log("f_verify_tlm_ectl_response_message: Failed to retrieve certificate from digest ", p_etsi_ts_103097_signed_data.content.signedData.signer.digest);
            if (p_check_security == true) {
              return false;
            }
          }
      }
      if (ischosen(p_etsi_ts_103097_signed_data.content.signedData.signature_.ecdsaBrainpoolP384r1Signature)) {
        v_result := f_verifyEcdsa(bit2oct(v_tbs), int2oct(0, 48), p_etsi_ts_103097_signed_data.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey);
Yann Garcia's avatar
Yann Garcia committed
      } else {
        v_result := f_verifyEcdsa(bit2oct(v_tbs), int2oct(0, 32), p_etsi_ts_103097_signed_data.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey);
Yann Garcia's avatar
Yann Garcia committed
      }
      if (v_result == false) {
        log("f_verify_tlm_ectl_response_message: Failed to verify signature");
Yann Garcia's avatar
Yann Garcia committed
        if (p_check_security == true) {
          return false;
        }
      }
      v_etsi_ts_102941_data_msg := oct2bit(p_etsi_ts_103097_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData);
Yann Garcia's avatar
Yann Garcia committed
      if (decvalue(v_etsi_ts_102941_data_msg, v_etsi_ts_102941_data) != 0) {
        log("f_verify_tlm_ectl_response_message: Failed to decode EtsiTs102941Data");
        return false;
      } else {
        log("f_verify_tlm_ectl_response_message: v_etsi_ts_102941_data= ", v_etsi_ts_102941_data);
        log("f_verify_pki_response_message: TlmCertificateTrustListMessage matching= ", match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_tlm_ctl));
        if (match(v_etsi_ts_102941_data, mw_etsiTs102941Data_to_be_signed_tlm_ctl) == false) {
          log("f_verify_tlm_ectl_response_message: Failed to decode certificateTrustListTlm");
          return false;
        } else {
          var Time32 v_time := (f_getCurrentTime()/* - 1072915200000*/) / 1000;
Yann Garcia's avatar
Yann Garcia committed
          p_to_be_signed_tlm_ectl := v_etsi_ts_102941_data.content.certificateTrustListTlm;
          log("f_verify_tlm_ectl_response_message: p_to_be_signed_tlm_ectl= ", p_to_be_signed_tlm_ectl);
          if (p_to_be_signed_tlm_ectl.nextUpdate <= v_time) {
            log("f_verify_tlm_ectl_response_message: Invalid nextUpdate value: compared values=", p_to_be_signed_tlm_ectl.nextUpdate, "/", v_time);
Yann Garcia's avatar
Yann Garcia committed
            return false;
          }
          // TODO Verify RCA certificate & signature
        }
      }

      return true;
    }

  } // End of group tlm

  group awaiting_messages {
Yann Garcia's avatar
Yann Garcia committed

    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 {
Yann Garcia's avatar
Yann Garcia committed
      var Headers 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(?/*FIXME YANN Blackberry 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, vc_eaHashedId8, 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;
Yann Garcia's avatar
Yann Garcia committed
          var Headers 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
              f_http_build_inner_ec_response(v_inner_ec_request/*Not required*/, cantparse, v_request_hash, -, -, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
              v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), v_headers));
            } else {
              f_http_build_inner_ec_response(v_inner_ec_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
YannGarcia's avatar
YannGarcia committed
              v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), v_headers));
              v_result := true;
YannGarcia's avatar
YannGarcia committed
            f_http_send(v_headers, v_response);
          }
        }
        [] tc_ac.timeout {
          log("f_await_ec_request_send_response: Expected message not received ***");
        }
      } // End of 'alt' statement
      
      return v_result;
    } // End of function f_await_ec_request_send_response