LibItsPki_Functions.ttcn 425 KB
Newer Older
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                                                           sha256,
                                                                           v_tbs,
                                                                           p_signer_identifier,
                                                                           m_signature_ecdsaNistP256(
                                                                                                     m_ecdsaP256Signature(
                                                                                                                          m_eccP256CurvePoint_x_only(
                                                                                                                                                     substr(v_tbs_signed, 0, 32)
                                                                                                                                                     ),
                                                                                                                          substr(v_tbs_signed, 32, 32)
                                                                                                                          )
                                                                                                     )
                                                                           )
                                                      );
      // Encode EtsiTs103097Data-Signed data structure
      v_encoded_inner_ec_response := bit2oct(encvalue(v_ieee1609dot2_signed_data));
      v_encrypted_inner_ec_response := fx_encrypt_aes_128_ccm_test(p_aes_sym_key, p_nonce, v_encoded_inner_ec_response);
      v_symkeyidentifier := '80'O & p_aes_sym_key;
      log("v_symkeyidentifier= ", v_symkeyidentifier);
      v_recipientId := f_hashedId8FromSha256(f_hashWithSha256(v_symkeyidentifier));
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log("v_recipientId= ", v_recipientId);
      // Fill Certificate template with the public compressed keys (canonical form)
      p_ieee1609dot2_signed_and_encrypted_data := valueof(
                                                          m_etsiTs103097Data_encrypted(
                                                                                       m_encryptedData(
                                                                                                       {
                                                                                                        m_recipientInfo_pskRecipInfo(
                                                                                                                                     v_recipientId
                                                                                                                                     )
                                                                                                       },
                                                                                                       m_symmetricCiphertext_aes128ccm(
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                                                                                                                       m_aesCcmCiphertext(
                                                                                                                                                          p_nonce,
                                                                                                                                                          v_encrypted_inner_ec_response
                                                                                                                                                         )
                                                                                                                                      )
                                                                                                      )
                                                                                       )
                                                         );
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log("<<< f_build_pki_secured_response_message: ", p_ieee1609dot2_signed_and_encrypted_data);
      return true;
    } // End of function f_build_pki_secured_response_message
    function f_read_pki_request_message(
                                  in Ieee1609Dot2Data p_encrypted_message,
                                  in Oct32 p_private_enc_key,
                                  in Oct32 p_salt,
                                  out Oct16 p_request_hash,
                                  out Oct16 p_aes_enc_key,
                                  out Ieee1609Dot2Data p_decrypted_message,
                                  out EtsiTs102941Data p_etsi_ts_102941_data
                                ) return boolean {
      var octetstring v_msg;
      var boolean ret := true;

      // 1. Calculate the request Hash
      v_msg := bit2oct(encvalue(p_encrypted_message));
      log("f_parse_pki_request: Encoded request: ", v_msg);
      p_request_hash := substr(f_hashWithSha256(v_msg), 0, 16);
      log("f_parse_pki_request: p_request_hash= ", p_request_hash);
      log("f_parse_pki_request: p_private_enc_key= ", p_private_enc_key);
      if (false == f_decrypt(p_private_enc_key, p_encrypted_message, p_salt, p_decrypted_message, p_aes_enc_key)) {
        log("f_parse_pki_request: Failed to decrypt message");
      log("f_parse_pki_request: v_ieee1609dot2_signed_data= ", p_decrypted_message);
      log("f_parse_pki_request: p_aes_enc_key= ", p_aes_enc_key);
      select(p_decrypted_message){
        case( mw_etsiTs103097Data_signed(
                    mw_signedData(
                            -,
                            mw_toBeSignedData(
                                    mw_signedDataPayload
                            )
                    )
              )
        ) {
            var bitstring v_msg_bit;
            v_msg_bit := oct2bit(p_decrypted_message.content.signedData.tbsData.payload.data.content.unsecuredData);
            if (decvalue(v_msg_bit, p_etsi_ts_102941_data) != 0) {
              ret := false;
            }
          }
          ret := false;
      }
      return ret;
    } // End of function f_read_pki_request_message

    function f_read_ec_request_from_iut_itss(
                                              in Ieee1609Dot2Data p_encrypted_message,
                                              out Oct16 p_request_hash,
                                              out Oct16 p_aes_enc_key,
                                              out Ieee1609Dot2Data p_decrypted_message,
                                              out EtsiTs102941Data p_etsi_ts_102941_data,
                                              out InnerEcRequest   p_inner_ec_request
                                            ) runs on ItsPkiHttp return boolean {
      // Local variables
      var PublicVerificationKey v_canonical_key;
      var EtsiTs103097Certificate v_ec_certificate;
      var HashedId8 v_ec_certificate_hashed_id8;
      var InnerEcResponse v_inner_ec_response;
/*      
      if(false == f_get_canonical_itss_key(v_canonical_key)){
        log(">>> f_read_ec_request_from_iut_itss: error getting canonical key");
        return false;
      }
*/
      if( f_read_pki_request_message( p_encrypted_message, vc_eaPrivateEncKey, vc_eaWholeHash/*salt*/,
                                          p_request_hash, p_aes_enc_key,
                                          p_decrypted_message,
                                          p_etsi_ts_102941_data
      )) {
        // decode InnerEcRequest 
        var bitstring 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_read_ec_request_from_iut_itss: Failed to decode InnerEcRequest");
        }
        return true;
      }
      return false;
    } // End of function f_read_ec_request_from_iut_itss

ASN.1 Documenter's avatar
ASN.1 Documenter committed
    /**
     * @desc Verify the protocol element of the Pki message. 
     *       If p_check_security is set to false, only decryption and decoding of the outer message are verified.
     * @param p_private_enc_key     Private key for decryption
     * @param p_salt
     * @param p_p_ieee1609dot2_encrypted_and_signed_data
     * @param p_check_security      Set to true to verify PKI protocol element such as signatures...
     * @param p_request_hash        The request hash for to be used to build the response
     * @param p_etsi_ts_102941_data The EtsiTs102941Data message
     * @param p_aes_enc_key         The AES 128 encrytion key to be used to encrypt the response
     * @return true on success, false otherwise
     */
    function f_verify_pki_request_message(
                                          in Oct32 p_private_enc_key,
                                          in Oct32 p_salt,
                                          in octetstring p_issuer_hash,
                                          in template (omit) PublicVerificationKey p_verification_key,
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                          in Ieee1609Dot2Data p_ieee1609dot2_encrypted_and_signed_data,
                                          in boolean p_check_security := true,
                                          out Oct16 p_request_hash,
                                          out HashedId8 p_bfk_request_hash,
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                          out EtsiTs102941Data p_etsi_ts_102941_data,
                                          out Oct16 p_aes_enc_key
                                          ) return boolean {
      // Local variables
      var bitstring v_msg_bit;
      var octetstring v_msg;
      var Oct32 v_hash;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      var Ieee1609Dot2Data v_ieee1609dot2_signed_data;
      var Certificate v_certificate;
      var charstring v_certificate_id;

      log(">>> f_verify_pki_request_message: p_private_enc_key= ", p_private_enc_key);
      log(">>> f_verify_pki_request_message: p_salt= ", p_salt);
      log(">>> f_verify_pki_request_message: p_issuer_hash= ", p_issuer_hash);
      log(">>> f_verify_pki_request_message: p_verification_key= ", p_verification_key);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log(">>> f_verify_pki_request_message: p_ieee1609dot2_encrypted_and_signed_data= ", p_ieee1609dot2_encrypted_and_signed_data);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // 1. Calculate the request Hash
      v_msg := bit2oct(encvalue(p_ieee1609dot2_encrypted_and_signed_data));
      log("f_verify_pki_request_message: Encoded request: ", v_msg);
      v_hash := f_hashWithSha256(v_msg);
      p_request_hash := substr(v_hash, 0, 16);
      //p_bfk_request_hash := f_hashedId8FromSha256(v_hash);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log("f_verify_pki_request_message: p_request_hash= ", p_request_hash);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // 2. Decrypt the InnerEcRequest
      log("f_verify_pki_request_message: p_private_enc_key= ", p_private_enc_key);
      if (f_decrypt(p_private_enc_key, p_ieee1609dot2_encrypted_and_signed_data, p_salt, v_ieee1609dot2_signed_data, p_aes_enc_key) == false) {
        log("f_verify_pki_request_message: Failed to decrypt message");
        return false;
      }
      log("f_verify_pki_request_message: v_ieee1609dot2_signed_data= ", v_ieee1609dot2_signed_data);
      log("f_verify_pki_request_message: p_aes_enc_key= ", p_aes_enc_key);

      // 3. Check basics security
      log(
          match(
                v_ieee1609dot2_signed_data,
                mw_etsiTs103097Data_signed(
                                           mw_signedData(
                                                         -,
                                                         mw_toBeSignedData(
                                                                           mw_signedDataPayload,
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                                                           )
                                                         )
                                )));
      if (match(v_ieee1609dot2_signed_data, mw_etsiTs103097Data_signed(mw_signedData(-, mw_toBeSignedData(mw_signedDataPayload)))) == false) {
        log("f_verify_pki_request_message: Failed to check basic security");
        if (p_check_security == true) {
          return false;
        }
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // 4. Verifiy signature
      log("f_verify_pki_request_message: v_ieee1609dot2_signed_data.content.signedData.tbsData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData);
      v_msg := bit2oct(encvalue(v_ieee1609dot2_signed_data.content.signedData.tbsData));
      if (not ispresent(p_verification_key)){
        var EtsiTs103097Certificate v_cert;
        var charstring v_cert_id;
        if (ischosen(v_ieee1609dot2_signed_data.content.signedData.signer.digest)){
          if (not f_getCertificateFromDigest(v_ieee1609dot2_signed_data.content.signedData.signer.digest, v_cert, v_cert_id)){
            if (p_check_security == true) {
              return false;
            }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
          }
        }
        if (ischosen(v_ieee1609dot2_signed_data.content.signedData.signer.certificate)){
          if(lengthof(v_ieee1609dot2_signed_data.content.signedData.signer.certificate) > 0){
            v_cert := v_ieee1609dot2_signed_data.content.signedData.signer.certificate[0];
ASN.1 Documenter's avatar
ASN.1 Documenter committed
          }
        }
        if (isbound(v_cert)){
          if(ischosen(v_cert.toBeSigned.verifyKeyIndicator.verificationKey)){
            p_verification_key := v_cert.toBeSigned.verifyKeyIndicator.verificationKey;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
          }
        }
      if (ispresent(p_verification_key)){
        log("f_verify_pki_request_message: v_msg= ", v_msg);
        if (false == f_verifyEcdsa(v_msg, int2oct(0, 32), v_ieee1609dot2_signed_data.content.signedData.signature_, valueof(p_verification_key))) {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
          if (p_check_security == true) {
            return false;
          }
        }
      }
      // 5. Return the PKI message
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log("f_verify_pki_request_message: v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData);
      v_msg_bit := oct2bit(v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData);
      if (decvalue(v_msg_bit, p_etsi_ts_102941_data) != 0) {
        if (p_check_security == true) {
          return false;
        }
      }
      if (p_etsi_ts_102941_data.version != PkiProtocolVersion) {
        if (p_check_security == true) {
          return false;
        }
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log("<<< f_verify_pki_request_message: true");
      return true;
    } // End of function f_verify_pki_request_message
    /**
     * @desc Verify the protocol element of the Pki message. 
     *       If p_check_security is set to false, only decryption and decoding of the outer message are verified.
     * @param p_private_enc_key     Private key for decryption
     * @param p_salt
     * @param p_p_ieee1609dot2_encrypted_and_signed_data
     * @param p_check_security      Set to true to verify PKI protocol element such as signatures...
     * @param p_request_hash        The request hash for to be used to build the response
     * @param p_etsi_ts_102941_data The EtsiTs102941Data message
     * @param p_aes_enc_key         The AES 128 encrytion key to be used to encrypt the response
     * @return true on success, false otherwise
     */
    function f_verify_pki_request_message_with_certificate(
                                                           in Oct32 p_private_enc_key,
                                                           in Oct32 p_salt,
                                                           in EtsiTs103097Certificate p_signer_certificate,
                                                           in Ieee1609Dot2Data p_ieee1609dot2_encrypted_and_signed_data,
                                                           in boolean p_check_security := true,
                                                           out Oct16 p_request_hash,
                                                           out HashedId8 p_bfk_request_hash,
                                                           out EtsiTs102941Data p_etsi_ts_102941_data,
                                                           out Oct16 p_aes_enc_key
                                                           ) return boolean {
      // Local variables
      var bitstring v_msg_bit;
      var octetstring v_msg;
      var Oct32 v_hash;
      var Ieee1609Dot2Data v_ieee1609dot2_signed_data;

      log(">>> f_verify_pki_request_message_with_certificate: p_private_enc_key= ", p_private_enc_key);
      log(">>> f_verify_pki_request_message_with_certificate: p_salt= ", p_salt);
      log(">>> f_verify_pki_request_message_with_certificate: p_signer_certificate= ", p_signer_certificate);
      log(">>> f_verify_pki_request_message_with_certificate: p_ieee1609dot2_encrypted_and_signed_data= ", p_ieee1609dot2_encrypted_and_signed_data);

      // 1. Calculate the request Hash
      v_msg := bit2oct(encvalue(p_ieee1609dot2_encrypted_and_signed_data));
      log("f_verify_pki_request_message_with_certificate: Encoded request: ", v_msg);
      v_hash := f_hashWithSha256(v_msg);
      p_request_hash := substr(v_hash, 0, 16);
      //p_bfk_request_hash := f_hashedId8FromSha256(v_hash);
      log("f_verify_pki_request_message_with_certificate: p_request_hash= ", p_request_hash);

      // 2. Decrypt the InnerEcRequest
      log("f_verify_pki_request_message_with_certificate: p_private_enc_key= ", p_private_enc_key);
      if (f_decrypt(p_private_enc_key, p_ieee1609dot2_encrypted_and_signed_data, p_salt, v_ieee1609dot2_signed_data, p_aes_enc_key) == false) {
        log("f_verify_pki_request_message_with_certificate: Failed to decrypt message");
        return false;
      }
      log("f_verify_pki_request_message_with_certificate: v_ieee1609dot2_signed_data= ", v_ieee1609dot2_signed_data);
      log("f_verify_pki_request_message_with_certificate: p_aes_enc_key= ", p_aes_enc_key);

      // 3. Check basics security
      log(
          match(
                v_ieee1609dot2_signed_data,
                mw_etsiTs103097Data_signed(
                                           mw_signedData(
                                                         -,
                                                         mw_toBeSignedData(
                                                                           mw_signedDataPayload,
                                                                           mw_ieee1609Dot2_headerInfo(c_its_aid_SCR)
                                                                           )
                                                         )
                                )));
      if (match(v_ieee1609dot2_signed_data, mw_etsiTs103097Data_signed(mw_signedData(-, mw_toBeSignedData(mw_signedDataPayload)))) == false) {
        log("f_verify_pki_request_message_with_certificate: Failed to check basic security");
        if (p_check_security == true) {
          return false;
        }
      }

      // 4. Verifiy signature
      log("f_verify_pki_request_message_with_certificate: v_ieee1609dot2_signed_data.content.signedData.tbsData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData);
      v_msg := bit2oct(encvalue(v_ieee1609dot2_signed_data.content.signedData.tbsData));
      log("f_verify_pki_request_message_with_certificate: v_msg= ", v_msg);
      
      var octetstring v_enc := bit2oct(encvalue(p_signer_certificate));
      var Oct32 v_issuer := f_hashWithSha256(v_enc);
      log("f_verify_pki_request_message_with_certificate: signing issuer= ", v_issuer);
      if (f_verifyEcdsa(v_msg, v_issuer, v_ieee1609dot2_signed_data.content.signedData.signature_, p_signer_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) {
        if (p_check_security == true) {
          return false;
        }
      }

      // 4. Return the PKI message
      log("f_verify_pki_request_message_with_certificate: v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData);
      v_msg_bit := oct2bit(v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData);
      if (decvalue(v_msg_bit, p_etsi_ts_102941_data) != 0) {
        if (p_check_security == true) {
          return false;
        }
      }
      if (p_etsi_ts_102941_data.version != PkiProtocolVersion) {
        if (p_check_security == true) {
          return false;
        }
      }

      log("<<< f_verify_pki_request_message_with_certificate: true");
      return true;
    } // End of function f_verify_pki_request_message_with_certificate_with_certificate

ASN.1 Documenter's avatar
ASN.1 Documenter committed
    /**
     * @desc Verify the protocol element of the Pki message. 
     *       If p_check_security is set to false, only decryption and decoding of the outer message are verified.
     * @param p_private_key         Private key for decryption
     * @param p_publicEphemeralCompressedKey
     * @param p_publicEphemeralCompressedKeyMode
     * @param p_issuer              Issuer
     * @param p_certificate         Certificate to use for verification key
     * @param p_ieee1609dot2_encrypted_and_signed_data The received encrypted and signed data
     * @param p_check_security      Set to true to verify PKI protocol element such as signatures...
     * @param p_response_type       Response type (0: InnerEcResponse, 1: InnerAtResponse...). Default: 0
     * @param p_etsi_ts_102941_data The EtsiTs102941Data message
     * @return true on success, false otherwise
     */
    function f_verify_pki_response_message(
                                           in octetstring p_private_enc_key,
                                           in Oct16 p_aes_sym_key,
                                           in Oct16 p_authentication_vector, // TODO Tobe removed
                                           in octetstring p_issuer,
                                           in Ieee1609Dot2Data p_ieee1609dot2_encrypted_and_signed_data,
                                           in boolean p_check_security := true,
                                           in integer p_response_type := 0,
                                           out EtsiTs102941Data p_etsi_ts_102941_data
                                           ) return boolean {
      // Local variables
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var octetstring v_plain_message;
      var Ieee1609Dot2Data v_ieee1609dot2_signed_data;
      var Certificate v_certificate;
      var charstring v_certificate_id;
      var bitstring v_etsi_ts_102941_data_msg;
      var bitstring v_tbs;
      var boolean v_ret;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log(">>> f_verify_pki_response_message: p_private_enc_key= ", p_private_enc_key);
      log(">>> f_verify_pki_response_message: p_aes_sym_key= ", p_aes_sym_key);
      log(">>> f_verify_pki_response_message: p_authentication_vector= ", p_authentication_vector);
      log(">>> f_verify_pki_response_message: p_issuer= ", p_issuer);
      log(">>> f_verify_pki_response_message: p_check_security= ", p_check_security);
      log(">>> f_verify_pki_response_message: p_response_type= ", p_response_type);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // TODO Check p_ieee1609dot2_encrypted_and_signed_data.content.encryptedData.recipients[0].pskRecipInfo. See IEEE Std 1609.2-2017 Clause 6.3.34 PreSharedKeyRecipientInfo
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // 1. Decrypt the data
      v_plain_message := fx_decrypt_aes_128_ccm_test(p_aes_sym_key, p_ieee1609dot2_encrypted_and_signed_data.content.encryptedData.ciphertext.aes128ccm.nonce, p_ieee1609dot2_encrypted_and_signed_data.content.encryptedData.ciphertext.aes128ccm.ccmCiphertext);
      if (isbound(v_plain_message) == false) {
        return false;
      }
      log("f_verify_pki_response_message: v_plain_message= ", v_plain_message);

      // 2. Decode it
      v_tbs := oct2bit(v_plain_message);
      if (decvalue(v_tbs, v_ieee1609dot2_signed_data) != 0) {
        return false;
      }
      log("f_verify_pki_response_message: v_ieee1609dot2_signed_data= ", v_ieee1609dot2_signed_data);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // 3. Check the signature
      log("f_verify_pki_response_message: v_ieee1609dot2_signed_data.content.signedData.tbsData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData);
      v_tbs := encvalue(v_ieee1609dot2_signed_data.content.signedData.tbsData);
      if (f_getCertificateFromDigest(v_ieee1609dot2_signed_data.content.signedData.signer.digest, v_certificate, v_certificate_id) == false) {
        if (p_check_security == true) {
          return false;
        }
      }
      if (f_verifyEcdsa(bit2oct(v_tbs), p_issuer, v_ieee1609dot2_signed_data.content.signedData.signature_, v_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) {
        if (p_check_security == true) {
          return false;
        }
      }

      // 4. Verify EtsiTs103097Data-Signed HeaderInfo
      // TODO Parameter p_response_type seems to be useless
      if ((p_response_type == 0) or (p_response_type == 1)) { // InnerEcResponse & InnerAtResponse
        log("f_verify_pki_response_message: headerInfo matching= ", match(v_ieee1609dot2_signed_data.content.signedData.tbsData.headerInfo, mw_headerInfo_inner_pki_response));
        if (match(v_ieee1609dot2_signed_data.content.signedData.tbsData.headerInfo, mw_headerInfo_inner_pki_response) == false) {
          if (p_check_security == true) {
            return false;
          }
        }
      } // else, no check
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // 5. Return the PKI message
      log("f_verify_pki_response_message: v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData);
      v_etsi_ts_102941_data_msg := oct2bit(v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData);
      if (decvalue(v_etsi_ts_102941_data_msg, p_etsi_ts_102941_data) != 0) {
        return false;
      }

      if (p_etsi_ts_102941_data.version != PkiProtocolVersion) {
        return false;
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      return true;
    } // End of function f_verify_pki_response_message
    function f_verify_repeated_request(
                                       in HttpMessage p_request_1,
                                       in HttpMessage p_request_2
                                       ) return boolean {

      return false;
    } // End of function f_verify_repeated_request
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    /**
     * @desc Verify the EC certificate generated by the EA entity
     * @param p_ec_certificate        The new EC certificate
     * @param p_ea_certificate        The certificate issuer
     * @param p_public_key_compressed The public compressed key (canonical form) generated for the InnerEcRequest
     * @param p_compressed_mode       The public compressed key mode
     * @return true on success, false otherwise
     */
    function f_verify_ec_certificate(
                                     in Certificate p_ec_certificate,
                                     in Certificate p_ea_certificate,
                                     in HashedId8 p_ea_hashed_id8,
                                     in octetstring p_public_key_compressed,
                                     in integer p_compressed_mode,
                                     out HashedId8 p_ec_cert_hashed_id8
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                     ) return boolean {
      var bitstring v_encoded_cert;
      var Oct32 v_ec_cert_hash_256;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Calculate the HashedId8 of the whole certificate
      v_encoded_cert := encvalue(p_ec_certificate);
      v_ec_cert_hash_256 := f_hashWithSha256(bit2oct(v_encoded_cert));
      log("f_verify_ec_certificate: ==> EC certificate Hash: ", v_ec_cert_hash_256);
      p_ec_cert_hashed_id8 := f_hashedId8FromSha256(v_ec_cert_hash_256);
      log("f_verify_ec_certificate: ==> EC certificate HashedId8: ", p_ec_cert_hashed_id8);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Check the signer
      log("f_verify_ec_certificate: Check the signer: ", match(p_ec_certificate.issuer, m_issuerIdentifier_sha256AndDigest(p_ea_hashed_id8)));
      log("f_verify_ec_certificate: Check the signer: ", match(p_ec_certificate.issuer, m_issuerIdentifier_sha384AndDigest(p_ea_hashed_id8)));
      if (
          (match(p_ec_certificate.issuer, m_issuerIdentifier_sha256AndDigest(p_ea_hashed_id8)) == false) and
          (match(p_ec_certificate.issuer, m_issuerIdentifier_sha384AndDigest(p_ea_hashed_id8)) == false)
          ) {
        log("f_verify_ec_certificate: Wrong issuer");
        return false;
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Check EC certificate signature
      if (f_verifyCertificateSignatureWithPublicKey(p_ec_certificate, p_ea_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) {
        log("f_verify_ec_certificate: Signature not verified");
        return false;
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // TODO Check that requested information are present
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      if (f_verifySspPermissions(p_ec_certificate.toBeSigned.appPermissions, p_ea_certificate.toBeSigned.appPermissions) == false) {
        log("f_verify_ec_certificate: Ssp permissions not verified");
        return false;
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      return true;
    } // End of function f_verify_ec_certificate
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    /**
     * @desc Verify the generated AT certificate 
     * @param p_at_certificate        The new AT certificate
     * @param p_ea_certificate        The certificate issuer
     * @param p_public_key_compressed The public compressed key (canonical form) generated for the InnerAtRequest
     * @param p_compressed_mode       The public compressed key mode
     * @return true on success, false otherwise
     */
    function f_verify_at_certificate(
                                     in Certificate p_at_certificate,
                                     in Certificate p_aa_certificate,
                                     in octetstring p_public_key_compressed,
                                     in integer p_compressed_mode
                                     ) return boolean {
      var bitstring v_encoded_cert;
      var HashedId8 v_at_cert_hashed_id8;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Calculate the HashedId8 of the whole certificate
      v_encoded_cert := encvalue(p_at_certificate);
      v_at_cert_hashed_id8 := f_hashedId8FromSha256(f_hashWithSha256(bit2oct(v_encoded_cert)));
      log("f_verify_at_certificate: EC certificate HashedId8: ", v_at_cert_hashed_id8);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Check the signer
      log("f_verify_at_certificate: ", match(p_at_certificate.issuer, mw_issuerIdentifier_self()));
      if (match(p_at_certificate.issuer, mw_issuerIdentifier_self)) {
        return false;
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Check EC certificate signature
      if (f_verifyCertificateSignatureWithPublicKey(p_at_certificate, p_aa_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) {
        log("f_verify_at_certificate: Signature not verified");
        return false;
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // TODO Check that requested information are present
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      if (f_verifySspPermissions(p_aa_certificate.toBeSigned.appPermissions, p_at_certificate.toBeSigned.appPermissions) == false) {
        log("f_verify_at_certificate: Ssp permissions not verified");
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        return false;
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      return true;
    } // End of function f_verify_at_certificate
ASN.1 Documenter's avatar
ASN.1 Documenter committed
  } // End of group inner_ec_xxx

  group altsteps {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    altstep a_default_pki_http() runs on ItsPkiHttp {
      [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(
                                                      mw_http_response(
                                                                       mw_http_response_ko
                                                                       )) {
        tc_ac.stop;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        log("*** " & testcasename() & ": FAIL: Unexpected message received ***");
        f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
      }
      [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(mw_http_request) {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP Request received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(mw_http_response) {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP Response received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [not(PICS_MULTIPLE_END_POINT)] httpPort.receive {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP message received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [] a_shutdown() {
        log("*** a_default: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***");
        stop;
      }
    } // End of altstep a_default_pki_http
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    altstep a_default_pki_http_ec() runs on ItsPkiHttp {
      [PICS_MULTIPLE_END_POINT] httpEcPort.receive(
                                                   mw_http_response(
                                                                    mw_http_response_ko
                                                                    )) {
        tc_ac.stop;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        log("*** " & testcasename() & ": FAIL: Unexpected message received ***");
        f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
      }
      [PICS_MULTIPLE_END_POINT] httpEcPort.receive(mw_http_request) {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP Request received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [PICS_MULTIPLE_END_POINT] httpEcPort.receive(mw_http_response) {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP Response received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [PICS_MULTIPLE_END_POINT] httpEcPort.receive {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP message received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [] a_shutdown() {
        log("*** a_default: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***");
        stop;
      }
    } // End of altstep a_default_pki_http_ec
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    altstep a_default_pki_http_atv() runs on ItsPkiHttp {
      [PICS_MULTIPLE_END_POINT] httpAtVPort.receive(
                                                   mw_http_response(
                                                                    mw_http_response_ko
                                                                    )) {
        tc_ac.stop;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        log("*** " & testcasename() & ": FAIL: Unexpected message received ***");
        f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
      }
      [PICS_MULTIPLE_END_POINT] httpAtVPort.receive(mw_http_request) {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP Request received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [PICS_MULTIPLE_END_POINT] httpAtVPort.receive(mw_http_response) {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP Response received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [PICS_MULTIPLE_END_POINT] httpAtVPort.receive {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP message received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [] a_shutdown() {
        log("*** a_default: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***");
        stop;
      }
    } // End of altstep a_default_pki_http_atv
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    altstep a_default_pki_http_at() runs on ItsPkiHttp {
      [PICS_MULTIPLE_END_POINT] httpAtPort.receive(
                                                   mw_http_response(
                                                                    mw_http_response_ko
                                                                    )) {
        tc_ac.stop;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        log("*** " & testcasename() & ": FAIL: Unexpected message received ***");
        f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
      }
      [PICS_MULTIPLE_END_POINT] httpAtPort.receive(mw_http_request) {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP Request received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [PICS_MULTIPLE_END_POINT] httpAtPort.receive(mw_http_response) {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP Response received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [PICS_MULTIPLE_END_POINT] httpAtPort.receive {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP message received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [] a_shutdown() {
        log("*** a_default: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***");
        stop;
      }
    } // End of altstep a_default_pki_http_at

    altstep a_default_pki_http_ca() runs on ItsPkiHttp {
      [PICS_MULTIPLE_END_POINT] httpCaPort.receive(
                                                   mw_http_response(
                                                                    mw_http_response_ko
                                                                    )) {
        tc_ac.stop;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        log("*** " & testcasename() & ": FAIL: Unexpected message received ***");
        f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
      }
      [PICS_MULTIPLE_END_POINT] httpCaPort.receive(mw_http_request) {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP Request received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [PICS_MULTIPLE_END_POINT] httpCaPort.receive(mw_http_response) {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP Response received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [PICS_MULTIPLE_END_POINT] httpCaPort.receive {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP message received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [] a_shutdown() {
        log("*** a_default: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***");
        stop;
      }
    } // End of altstep a_default_pki_http_ca

    altstep a_default_pki_http_tlm() runs on ItsPkiHttp {
      [PICS_MULTIPLE_END_POINT] httpTlmPort.receive(
                                                   mw_http_response(
                                                                    mw_http_response_ko
                                                                    )) {
        tc_ac.stop;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        log("*** " & testcasename() & ": FAIL: Unexpected message received ***");
        f_selfOrClientSyncAndVerdictTestBody(c_tbDone, e_error);
      }
      [PICS_MULTIPLE_END_POINT] httpTlmPort.receive(mw_http_request) {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP Request received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [PICS_MULTIPLE_END_POINT] httpTlmPort.receive(mw_http_response) {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP Response received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [PICS_MULTIPLE_END_POINT] httpTlmPort.receive {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP message received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [] a_shutdown() {
        log("*** a_default: INFO: TEST COMPONENT NOW STOPPING ITSELF! ***");
        stop;
      }
    } // End of altstep a_default_pki_http_tlm

    altstep a_await_ec_http_request_from_iut(
                                              template HttpMessage p_http_message,
                                              out HttpMessage p_request
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                              ) runs on ItsPkiHttp {
      [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        log("a_await_ec_http_request_from_iut: Received message on httpPort");
      }
      [PICS_MULTIPLE_END_POINT] httpEcPort.receive(p_http_message) -> value p_request {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        log("a_await_ec_http_request_from_iut: Received message on httpEcPort");
      }
    } // End of altstep a_await_ec_http_request_from_iut
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    altstep a_await_ec_http_response_from_iut(
                                              template HttpMessage p_http_message,
                                              out HttpMessage p_response
                                              ) runs on ItsPkiHttp {
      [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_response {
        log("a_await_ec_http_response_from_iut: Received message on httpPort");
      }
      [PICS_MULTIPLE_END_POINT] httpEcPort.receive(p_http_message) -> value p_response {
        log("a_await_ec_http_response_from_iut: Received message on httpEcPort");
      }
    } // End of altstep a_await_ec_http_response_from_iut
    altstep a_await_at_http_request_from_iut(
                                             template HttpMessage p_http_message,
                                             out HttpMessage p_request
                                             ) runs on ItsPkiHttp {
      [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request {
        log("a_await_at_http_request_from_iut: Received message on httpPort");
      }
      [PICS_MULTIPLE_END_POINT] httpAtPort.receive(p_http_message) -> value p_request {
        log("a_await_at_http_request_from_iut: Received message on httpAtPort");
      }
    } // End of altstep a_await_at_http_request_from_iut
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    altstep a_await_at_http_response_from_iut(
                                              template HttpMessage p_http_message,
                                              out HttpMessage p_response
                                              ) runs on ItsPkiHttp {
      [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_response {
        log("a_await_at_http_response_from_iut: Received message on httpPort");
      }
      [PICS_MULTIPLE_END_POINT] httpAtPort.receive(p_http_message) -> value p_response {
        log("a_await_at_http_response_from_iut: Received message on httpAtPort");
      }
    } // End of altstep a_await_at_http_response_from_iut
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    altstep a_await_atv_http_request_from_iut(
                                              template HttpMessage p_http_message,
                                              out HttpMessage p_request
                                              ) runs on ItsPkiHttp {
      [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request {
        log("a_await_atv_http_request_from_iut: Received message on httpPort");
      }
      [PICS_MULTIPLE_END_POINT] httpAtVPort.receive(p_http_message) -> value p_request {
        log("a_await_avt_http_request_from_iut: Received message on httpAtVPort");
      }
    } // End of altstep a_await_atv_http_request_from_iut
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    altstep a_await_atv_http_response_from_iut(
                                              template HttpMessage p_http_message,
                                              out HttpMessage p_response
                                              ) runs on ItsPkiHttp {
      [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_response {
        log("a_await_atv_http_response_from_iut: Received message on httpPort");
      }
      [PICS_MULTIPLE_END_POINT] httpAtVPort.receive(p_http_message) -> value p_response {
        log("a_await_avt_http_response_from_iut: Received message on httpAtVPort");
      }
    } // End of altstep a_await_atv_http_response_from_iut
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    altstep a_await_dc_http_request_from_iut(
                                              template HttpMessage p_http_message,
                                              out HttpMessage p_request
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                              ) runs on ItsPkiHttp {
      [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        log("a_await_dc_http_request_from_iut: Received message on httpPort");
      }
      [PICS_MULTIPLE_END_POINT] httpCaPort.receive(p_http_message) -> value p_request {
        log("a_await_dc_http_request_from_iut: Received message on httpCaPort");
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
    } // End of altstep a_await_dc_http_request_from_iut
    altstep a_await_ctl_http_request_from_iut(
                                              template HttpMessage p_http_message,
                                              out HttpMessage p_request
                                              ) runs on ItsPkiHttp {
      [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request {
        log("a_await_ctl_http_request_from_iut: Received message on httpPort");
      }
      [PICS_MULTIPLE_END_POINT] httpCaPort.receive(p_http_message) -> value p_request {
        log("a_await_ctl_http_request_from_iut: Received message on httpCaPort");
      }
    } // End of altstep a_await_ctl_http_request_from_iut
    altstep a_await_crl_http_request_from_iut(
                                              template HttpMessage p_http_message,
                                              out HttpMessage p_request
                                              ) runs on ItsPkiHttp {
      [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request {
        log("a_await_crl_http_request_from_iut: Received message on httpPort");
      }
      [PICS_MULTIPLE_END_POINT] httpCaPort.receive(p_http_message) -> value p_request {
        log("a_await_crl_http_request_from_iut: Received message on httpCaPort");
      }
    } // End of altstep a_await_crl_http_request_from_iut
    altstep a_await_cpoc_http_request_from_iut(
                                               template HttpMessage p_http_message,
                                               out HttpMessage p_request
      [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request {
        log("a_await_cpoc_http_request_from_iut: Received message on httpPort");
      }
      [PICS_MULTIPLE_END_POINT] httpCaPort.receive(p_http_message) -> value p_request {
        log("a_await_cpoc_http_request_from_iut: Received message on httpCaPort");
      }
    } // End of altstep a_await_cpoc_http_request_from_iut
    altstep a_await_any_http_request_from_iut(
                                               template HttpMessage p_http_message,
                                               out HttpMessage p_request
                                               ) runs on ItsPkiHttp {
      [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(p_http_message) -> value p_request {
        log("a_await_any_http_request_from_iut: Received message on httpPort");
      }
      [PICS_MULTIPLE_END_POINT] httpCaPort.receive(p_http_message) -> value p_request {
        log("a_await_any_http_request_from_iut: Received message on httpEcPort");
      }
    } // End of altstep a_await_any_http_request_from_iut
ASN.1 Documenter's avatar
ASN.1 Documenter committed
  } // End of group altsteps
ASN.1 Documenter's avatar
ASN.1 Documenter committed
} // End of module LibItsPki_Functions