LibItsPki_Functions.ttcn 375 KB
Newer Older
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        v_result := f_build_pki_secured_request_message_signed_with_pop(v_private_key, valueof(m_signerIdentifier_self), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), PX_EC_ALG_FOR_EC, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
      } else { // We use last valid EC certificate
        // TODO Retrieve EC certificate from the first enrolment instead of PX
        log("f_http_build_inner_ec_request: v_ec_private_key: ", vc_ec_private_keys[vc_ec_keys_counter - 1]);
        log("f_http_build_inner_ec_request: v_ec_public_compressed_key: ", vc_ec_public_compressed_key[vc_ec_keys_counter - 1]);
        log("f_http_build_inner_ec_request: v_ec_compressed_modes: ", vc_ec_compressed_modes[vc_ec_keys_counter - 1]);
        log("f_http_build_inner_ec_request: v_ec_hashed_id8: ", vc_ec_hashed_id8[vc_ec_keys_counter - 1]);
        v_result := f_build_pki_secured_request_message_signed_with_pop(vc_ec_private_keys[vc_ec_keys_counter - 1], valueof(m_signerIdentifier_digest(vc_ec_hashed_id8[vc_ec_keys_counter - 1])), vc_ec_hashed_id8[vc_ec_keys_counter - 1]/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), PX_EC_ALG_FOR_EC, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      if (v_result == false) {
        log("*** f_http_build_inner_ec_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      } else {
        log("f_http_build_inner_ec_request: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
        log("f_http_build_inner_ec_request: p_request_hash= ", p_request_hash);
      }
    } // End of function f_http_build_inner_ec_request

    function f_http_build_inner_ec_request_with_wrong_parameters( // TODO Cleanup parameters
                                                                 in SequenceOfPsidSsp p_appPermissions,
                                                                 in octetstring p_canonical_id := PICS_ITS_S_CANONICAL_ID,
                                                                 in Time32 p_start,
                                                                 in Duration p_duration,
                                                                 in boolean p_alter_private_key := false,
                                                                 out octetstring p_private_key,
                                                                 out octetstring p_public_key_compressed,
                                                                 out integer p_compressed_mode,
                                                                 out Oct16 p_aes_sym_key,
                                                                 out Oct16 p_encrypted_sym_key,
                                                                 out Oct16 p_authentication_vector,
                                                                 out Oct12 p_nonce,
                                                                 out octetstring p_salt,
                                                                 out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
                                                                 out Oct32 p_request_hash
                                                                 ) runs on ItsPkiHttp {
      var InnerEcRequest v_inner_ec_request;
      var Ieee1609Dot2Data v_inner_ec_request_signed_for_pop;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var boolean v_result;

      log(">>> f_http_build_inner_ec_request_with_wrong_parameters");
      if (f_generate_inner_ec_request_with_wrong_parameters(p_appPermissions, p_canonical_id, p_start, p_duration, p_alter_private_key, p_private_key, p_public_key_compressed, p_compressed_mode, v_inner_ec_request) == false) {
        log("*** f_http_build_inner_ec_request_with_wrong_parameters: ERROR: Failed to generate InnerEcRequest ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log ("f_http_build_inner_ec_request_with_wrong_parameters: ==> EC verification private key: ", p_private_key);
      log ("f_http_build_inner_ec_request_with_wrong_parameters: ==> EC verification public compressed key: ", p_public_key_compressed);
      log ("f_http_build_inner_ec_request_with_wrong_parameters: ==> EC verification public compressed mode: ", p_compressed_mode);
      // Generate InnerEcRequestSignedForPoP
      if (f_generate_inner_ec_request_signed_for_pop(p_private_key, v_inner_ec_request, v_inner_ec_request_signed_for_pop) == false) {
        log("*** f_http_build_inner_ec_request_with_wrong_parameters: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("f_http_build_inner_ec_request_with_wrong_parameters: v_inner_ec_request_signed_for_pop= ", v_inner_ec_request_signed_for_pop);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Secure InnerEcRequestSignedForPoP message
      if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_inner_ec_request_with_wrong_parameters: ERROR: Non canonical EA certificate ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("f_http_build_inner_ec_request_with_wrong_parameters: Public encryption key: ", v_public_enc_key);
      log("f_http_build_inner_ec_request_with_wrong_parameters: Public encryption key comp: ", v_compressed_enc_key_mode);
      p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3.
      var octetstring v_private_key;
      if (PX_VE_ALG == e_nist_p256) {
        v_private_key := PICS_ITS_S_SIGN_NITSP256_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_brainpool_p256_r1) {
        v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP256r1_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_sm2_p256) {
        v_private_key := PICS_ITS_S_SIGN_SM2P256_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_nist_p384) {
        v_private_key := PICS_ITS_S_SIGN_NISTP384_PRIVATE_KEY;
      } else {
        v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP384r1_PRIVATE_KEY;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      v_result := f_build_pki_secured_request_message_signed_with_pop(v_private_key, valueof(m_signerIdentifier_self), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), PX_EC_ALG_FOR_EC, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      if (v_result == false) {
        log("*** f_http_build_inner_ec_request_with_wrong_parameters: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      } else {
        log("f_http_build_inner_ec_request_with_wrong_parameters: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
        log("f_http_build_inner_ec_request_with_wrong_parameters: p_request_hash= ", p_request_hash);
      }
    } // End of function f_http_build_inner_ec_request_with_wrong_parameters

    function f_http_build_invalid_enrolment_request(
                                                    out octetstring p_private_key,
                                                    out octetstring p_public_key_compressed,
                                                    out integer p_compressed_mode,
                                                    out Oct16 p_aes_sym_key,
                                                    out Oct16 p_encrypted_sym_key,
                                                    out Oct16 p_authentication_vector,
                                                    out Oct12 p_nonce,
                                                    out octetstring p_salt,
                                                    out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
                                                    out Oct32 p_request_hash
                                                    ) runs on ItsPkiHttp {
      var InnerEcRequest v_inner_ec_request;
      var Ieee1609Dot2Data v_inner_ec_request_signed_for_pop;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var boolean v_ret_code;
      var octetstring v_private_key;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      if (f_generate_inner_ec_request(p_private_key, p_public_key_compressed, p_compressed_mode, v_inner_ec_request) == false) {
        log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequest ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log ("f_http_build_invalid_enrolment_request: EC verification private key: ", p_private_key);
      log ("f_http_build_invalid_enrolment_request: EC verification public compressed key: ", p_public_key_compressed);
      log ("f_http_build_invalid_enrolment_request: EC verification public compressed mode: ", p_compressed_mode);
      // Generate InnerEcRequestSignedForPoP
      if (f_generate_inner_ec_request_signed_for_pop(p_private_key, v_inner_ec_request, v_inner_ec_request_signed_for_pop) == false) {
        log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("f_http_build_invalid_enrolment_request: v_inner_ec_request_signed_for_pop= ", v_inner_ec_request_signed_for_pop);
      // Modify signature to get an error
      if (ischosen(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaNistP256Signature)) {
        v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaNistP256Signature.sSig[1] := bit2oct('10101010'B xor4b oct2bit(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaNistP256Signature.sSig[1]));
      } else if (ischosen(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP256r1Signature)) {
        v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.sSig[1] := bit2oct('10101010'B xor4b oct2bit(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.sSig[1]));
      } else {
        v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP384r1Signature.sSig[1] := bit2oct('10101010'B xor4b oct2bit(v_inner_ec_request_signed_for_pop.content.signedData.signature_.ecdsaBrainpoolP384r1Signature.sSig[1]));
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Secure InnerEcRequestSignedForPoP message
      if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_invalid_enrolment_request: ERROR: Non canonical EA certificate ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("*** f_http_build_invalid_enrolment_request: Public encryption key: ", v_public_enc_key);
      log("*** f_http_build_invalid_enrolment_request: Public encryption key comp: ", v_compressed_enc_key_mode);
      p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3.
      if (PX_VE_ALG == e_nist_p256) {
        v_private_key := PICS_ITS_S_SIGN_NITSP256_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_brainpool_p256_r1) {
        v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP256r1_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_sm2_p256) {
        v_private_key := PICS_ITS_S_SIGN_SM2P256_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_nist_p384) {
        v_private_key := PICS_ITS_S_SIGN_NISTP384_PRIVATE_KEY;
      } else {
        v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP384r1_PRIVATE_KEY;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      }
      v_ret_code := f_build_pki_secured_request_message_signed_with_pop(v_private_key, valueof(m_signerIdentifier_self), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_inner_ec_request_signed_for_pop(v_inner_ec_request_signed_for_pop))), PX_EC_ALG_FOR_EC, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      if (v_ret_code == false) {
        log("*** f_http_build_invalid_enrolment_request: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("*** f_http_build_invalid_enrolment_request: DEBUG: p_ieee1609dot2_signed_and_encrypted_data = ", p_ieee1609dot2_signed_and_encrypted_data);
    } // End of function f_http_build_invalid_enrolment_request

    function f_http_build_inner_ec_response(
                                            in template (omit) InnerEcRequest p_inner_ec_request := omit,
                                            in EnrolmentResponseCode p_responseCode := ok,
                                            in Oct16 p_request_hash,
                                            in octetstring p_private_key := ''O,
                                            in octetstring p_digest := ''O,
                                            in Oct16 p_aes_sym_key,
                                            out EtsiTs103097Certificate p_ec_certificate,
                                            out HashedId8 p_ec_certificate_hashed_id8,
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                            out InnerEcResponse p_inner_ec_response,
                                            out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data
                                            ) return boolean {
      // Local variables
      var bitstring v_msg_bit;
      var octetstring v_msg;
      var Oct12 v_nonce;
      var Ieee1609Dot2Data v_ieee1609dot2_signed_data;
      var boolean p_result := false;

      log(">>> f_http_build_inner_ec_response: p_inner_ec_request= ", p_inner_ec_request);
      log(">>> f_http_build_inner_ec_response: p_responseCode= ", p_responseCode);
      log(">>> f_http_build_inner_ec_response: p_request_hash= ", p_request_hash);
      log(">>> f_http_build_inner_ec_response: p_private_key= ", p_private_key);
      log(">>> f_http_build_inner_ec_response: p_digest= ", p_digest);
      log(">>> f_http_build_inner_ec_response: p_aes_sym_key= ", p_aes_sym_key);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Check expectred response
      if (p_responseCode != ok) {
        p_inner_ec_response := valueof(
                                       m_innerEcResponse_ko(
                                                            p_request_hash,
                                                            p_responseCode
                                                            )
                                       );
        p_result := true;
      } else {
        // Generate the certificate
        if (f_generate_ec_certificate_for_inner_ec_response(valueof(p_inner_ec_request), p_private_key, p_digest, p_ec_certificate, p_ec_certificate_hashed_id8) == false) {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
          log("f_http_build_inner_ec_response: Failed to generate the certificate");
          p_inner_ec_response := valueof(
                                         m_innerEcResponse_ko(
                                                              p_request_hash,
                                                              incompleterequest
                                                              )
                                         );
        } else {
          p_inner_ec_response := valueof(
                                         m_innerEcResponse_ok(
                                                              p_request_hash,
                                                              p_ec_certificate
ASN.1 Documenter's avatar
ASN.1 Documenter committed
                                                              )
                                         );
        }
      }

      // Secure the response
      log("f_http_build_inner_ec_response: p_inner_ec_response= ", p_inner_ec_response);
      v_msg := bit2oct(encvalue(m_etsiTs102941Data_inner_ec_response(p_inner_ec_response)));
      v_nonce := substr(f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 16)), 0, 12); // Random value
      // TODO Consider  Sha384: m_signerIdentifier_digest(f_hashedId8FromSha384(p_digest))
      if (f_build_pki_secured_response_message(p_private_key,
                                               valueof(m_signerIdentifier_digest(f_hashedId8FromSha256(p_digest))),//  in SignerIdentifier p_signer_identifier,
                                               v_msg,
                                               p_aes_sym_key,
                                               v_nonce,
                                               p_ieee1609dot2_signed_and_encrypted_data
                                               ) == false) {
        log("f_http_build_inner_ec_response: Failed to generate the certificate");
        p_inner_ec_response := valueof(
                                       m_innerEcResponse_ko(
                                                            p_request_hash,
                                                            deniedrequest
                                                            )
                                       );
      } else {
        p_result := true;
      }

      return p_result;
    } // End of function f_http_build_inner_ec_response
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_http_build_authorization_request(
                                                in Certificate p_ec_certificate, // Enrolment credentials certificate
                                                in octetstring p_ec_private_key,
                                                out octetstring p_private_key,
                                                out octetstring p_public_key_compressed,
                                                out integer p_compressed_key_mode,
                                                out octetstring p_private_enc_key,
                                                out octetstring p_public_compressed_enc_key,
                                                out integer p_compressed_enc_key_mode,
                                                out Oct16 p_aes_sym_key,
                                                out Oct16 p_encrypted_sym_key,
                                                out Oct16 p_authentication_vector,
                                                out Oct12 p_nonce,
                                                out octetstring p_salt,
                                                out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
                                                out Oct32 p_request_hash
                                                ) runs on ItsPkiHttp {
      // Local variables
      var octetstring v_public_key_x;
      var octetstring v_public_key_y;
      var octetstring v_public_enc_key_x;
      var octetstring v_public_enc_key_y;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var InnerAtRequest v_inner_at_request;
      var Ieee1609Dot2Data v_inner_at_request_data;
      var InnerAtRequest v_authorization_request;
      var bitstring v_authorization_request_msg;

      // Generate the InnerAtRequest
      if (f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, p_ec_certificate, p_ec_private_key, p_private_key, p_public_key_compressed, p_compressed_key_mode, p_private_enc_key, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_inner_at_request) == false) {
        log("*** f_http_build_authorization_request: ERROR: Failed to generate AuthorizationRequest ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
        return;
      }
      log("f_http_build_authorization_request: v_inner_at_request= ", v_inner_at_request);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Secure InnerAtRequest message
      if (f_extract_enc_key(vc_aaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_authorization_request: ERROR: Non canonical AA certificate ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("*** f_http_build_authorization_request: Public encryption key: ", v_public_enc_key);
      log("*** f_http_build_authorization_request: Public encryption key comp: ", v_compressed_enc_key_mode);
      p_salt := vc_aaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3.
      log("*** f_http_build_authorization_request: p_salt: ", p_salt);
      if (PICS_PKI_AUTH_POP) {
        if(f_build_pki_secured_request_message_signed_with_pop(p_private_key, valueof(m_signerIdentifier_self), vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
          log("*** f_http_build_authorization_request: ERROR: Failed to generate Authorization Request ***");
          f_selfOrClientSyncAndVerdict("error", e_error);
        }
      } else { // Only encryption of EtsiTs102941Data/InnerAtRequest
        log("*** f_http_build_authorization_request: POP signature not applied");
        if(f_build_pki_secured_request_message_for_authorization(vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
          log("*** f_http_build_authorization_request: ERROR: Failed to generate Authorization Request ***");
          f_selfOrClientSyncAndVerdict("error", e_error);
        }
      }
      log("<<< f_http_build_authorization_request: DEBUG: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
      log("<<< f_http_build_authorization_request: DEBUG: p_request_hash= ", p_request_hash);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    } // End of function f_http_build_authorization_request

    function f_http_build_authorization_request_with_wrong_private_key(
                                                                       in Certificate p_ec_certificate, // Enrolment credentials certificate
                                                                       in octetstring p_ec_private_key,
                                                                       out octetstring p_private_key,
                                                                       out octetstring p_public_key_compressed,
                                                                       out integer p_compressed_key_mode,
                                                                       out octetstring p_private_enc_key,
                                                                       out octetstring p_public_compressed_enc_key,
                                                                       out integer p_compressed_enc_key_mode,
                                                                       out Oct16 p_aes_sym_key,
                                                                       out Oct16 p_encrypted_sym_key,
                                                                       out Oct16 p_authentication_vector,
                                                                       out Oct12 p_nonce,
                                                                       out octetstring p_salt,
                                                                       out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
                                                                       out Oct32 p_request_hash
                                                                       ) runs on ItsPkiHttp {
      // Local variables
      var octetstring v_public_key_x;
      var octetstring v_public_key_y;
      var octetstring v_public_enc_key_x;
      var octetstring v_public_enc_key_y;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var InnerAtRequest v_inner_at_request;
      var Ieee1609Dot2Data v_inner_at_request_data;
      var InnerAtRequest v_authorization_request;
      var bitstring v_authorization_request_msg;

      // Generate the InnerAtRequest
      if (f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, p_ec_certificate, p_ec_private_key, p_private_key, p_public_key_compressed, p_compressed_key_mode, p_private_enc_key, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_inner_at_request) == false) {
        log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Failed to generate AuthorizationRequest ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
        return;
      }
      log("f_http_build_authorization_request_with_wrong_private_key: v_inner_at_request= ", v_inner_at_request);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Secure InnerAtRequest message
      /***
          Use the wrong private key
      ***/
      if (f_extract_enc_key(vc_eaCertificate/*Insted of vc_aaCertificate/*/, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Non canonical EA certificate ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("*** f_http_build_authorization_request_with_wrong_private_key: Public encryption key: ", v_public_enc_key);
      log("*** f_http_build_authorization_request_with_wrong_private_key: Public encryption key comp: ", v_compressed_enc_key_mode);
      p_salt := vc_aaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3.
      log("*** f_http_build_authorization_request_with_wrong_private_key: p_salt: ", p_salt);
      if (PICS_PKI_AUTH_POP) {
        if(f_build_pki_secured_request_message_signed_with_pop(p_private_key, valueof(m_signerIdentifier_self), vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
          log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Failed to generate Authorization Request ***");
          f_selfOrClientSyncAndVerdict("error", e_error);
        }
      } else { // Only encryption of EtsiTs102941Data/InnerAtRequest
        log("*** f_http_build_authorization_request_with_wrong_private_key: POP signature not applied");
        if(f_build_pki_secured_request_message_for_authorization(vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
          log("*** f_http_build_authorization_request_with_wrong_private_key: ERROR: Failed to generate Authorization Request ***");
          f_selfOrClientSyncAndVerdict("error", e_error);
        }
      }
      log("*** f_http_build_authorization_request_with_wrong_private_key: DEBUG: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
      log("*** f_http_build_authorization_request_with_wrong_private_key: DEBUG: p_request_hash= ", p_request_hash);
    } // End of function f_http_build_authorization_request_with_wrong_private_key

    function f_http_build_authorization_request_with_wrong_parameters(
                                                                      in Certificate p_ec_certificate, // Enrolment credentials certificate
                                                                      in octetstring p_ec_private_key,
                                                                      in boolean p_alter_pop_signature := false,
                                                                      in boolean p_alter_hmac := false,
                                                                      in boolean p_alter_signer_digest := false,
                                                                      in boolean p_alter_pks_recipient := false,
                                                                      in boolean p_alter_enc_key := false,
                                                                      in boolean p_alter_ea_id := false,
                                                                      in template (omit) Time32 p_start := omit,
                                                                      in template (omit) Duration p_duration := omit,
                                                                      in template (omit) Time64 p_generation_time := omit,
                                                                      out octetstring p_private_key,
                                                                      out octetstring p_public_key_compressed,
                                                                      out integer p_compressed_key_mode,
                                                                      out octetstring p_private_enc_key,
                                                                      out octetstring p_public_compressed_enc_key,
                                                                      out integer p_compressed_enc_key_mode,
                                                                      out Oct16 p_aes_sym_key,
                                                                      out Oct16 p_encrypted_sym_key,
                                                                      out Oct16 p_authentication_vector,
                                                                      out Oct12 p_nonce,
                                                                      out octetstring p_salt,
                                                                      out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
                                                                      out Oct32 p_request_hash
                                                                      ) runs on ItsPkiHttp {
      // Local variables
      var octetstring v_public_key_x;
      var octetstring v_public_key_y;
      var octetstring v_public_enc_key_x;
      var octetstring v_public_enc_key_y;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var InnerAtRequest v_inner_at_request;
      var Ieee1609Dot2Data v_inner_at_request_data;
      var InnerAtRequest v_authorization_request;
      var bitstring v_authorization_request_msg;
      var boolean v_ret_code;

      // Generate the InnerAtRequest
      if (p_alter_ea_id == true) {
        var HashedId8 v_ea_hashed_id8 := vc_eaHashedId8;
        v_ea_hashed_id8[0] := 'bb'O;
        v_ea_hashed_id8[1] := 'cc'O;
        log("f_http_build_authorization_request_with_wrong_parameters: Altered eaId= ", v_ea_hashed_id8);
        v_ret_code := f_generate_inner_at_request(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, v_ea_hashed_id8, p_ec_certificate, p_ec_private_key, p_private_key, p_public_key_compressed, p_compressed_key_mode, p_private_enc_key, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_inner_at_request);
      } else {
        v_ret_code := f_generate_inner_at_request_with_wrong_parameters(vc_aaCertificate, -, vc_aaHashedId8, vc_eaCertificate, vc_eaWholeHash/*salt*/, vc_eaHashedId8, p_ec_certificate, p_ec_private_key, p_alter_hmac, p_alter_signer_digest, p_start, p_duration, p_generation_time, p_private_key, p_public_key_compressed, p_compressed_key_mode, p_private_enc_key, p_public_compressed_enc_key, p_compressed_enc_key_mode, v_inner_at_request);
      }
      if (v_ret_code == false) {
        log("*** f_http_build_authorization_request_with_wrong_parameters: ERROR: Failed to generate AuthorizationRequest ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
        return;
      }
      log("f_http_build_authorization_request_with_wrong_parameters: v_inner_at_request= ", v_inner_at_request);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Secure InnerAtRequest message
      if (f_extract_enc_key(vc_aaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_authorization_request_with_wrong_parameters: ERROR: Non canonical AA certificate ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("*** f_http_build_authorization_request_with_wrong_parameters: Public encryption key: ", v_public_enc_key);
      log("*** f_http_build_authorization_request_with_wrong_parameters: Public encryption key comp: ", v_compressed_enc_key_mode);
      p_salt := vc_aaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3.
      log("*** f_http_build_authorization_request_with_wrong_parameters: p_salt: ", p_salt);
      if (PICS_PKI_AUTH_POP) {
        if(f_build_pki_secured_request_message_signed_with_pop(p_private_key, valueof(m_signerIdentifier_self), vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_alter_pop_signature, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
          log("*** f_http_build_authorization_request_with_wrong_parameters: ERROR: Failed to generate Authorization Request ***");
          f_selfOrClientSyncAndVerdict("error", e_error);
        }
      } else { // Only encryption of EtsiTs102941Data/InnerAtRequest
        log("*** f_http_build_authorization_request_with_wrong_parameters: POP signature not applied");
        if(f_build_pki_secured_request_message_for_authorization(vc_aaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_request(v_inner_at_request))), PX_EC_ALG_FOR_AT, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
          log("*** f_http_build_authorization_request_with_wrong_parameters: ERROR: Failed to generate Authorization Request ***");
          f_selfOrClientSyncAndVerdict("error", e_error);
        }
      }
      log("*** f_http_build_authorization_request_with_wrong_parameters: DEBUG: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
      if (p_alter_enc_key == true) {
        /***
            Alter encryption key to prevent decryption
         ***/
        if (ischosen(p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].certRecipInfo.encKey.eciesNistP256)) {
          p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].certRecipInfo.encKey.eciesNistP256.c[1] := 'aa'O;
          p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].certRecipInfo.encKey.eciesNistP256.c[2] := 'bb'O;
        } else {
          p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].certRecipInfo.encKey.eciesBrainpoolP256r1.c[1] := 'aa'O;
          p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].certRecipInfo.encKey.eciesBrainpoolP256r1.c[2] := 'bb'O;
        }
        log("*** f_http_build_authorization_request_with_wrong_parameters: DEBUG: Altered enc key= ", p_ieee1609dot2_signed_and_encrypted_data);
      }
      if (p_alter_pks_recipient == true) {
        p_ieee1609dot2_signed_and_encrypted_data.content.encryptedData.recipients[0].pskRecipInfo := int2oct(314259265, 8); // NOT equal to the HashedId8 of the certificate CERT_AA
        log("*** f_http_build_authorization_request_with_wrong_parameters: DEBUG: Altered pskRecipInfo= ", p_ieee1609dot2_signed_and_encrypted_data);
      }
      log("*** f_http_build_authorization_request_with_wrong_parameters: DEBUG: p_request_hash= ", p_request_hash);
    } // End of function f_http_build_authorization_request_with_wrong_parameters

    function f_http_build_authorization_response(
                                                 in template (omit) InnerAtRequest p_inner_at_request := omit,
                                                 in AuthorizationResponseCode p_responseCode := ok,
                                                 in Oct16 p_request_hash,
                                                 in octetstring p_private_key := ''O,
                                                 in octetstring p_digest := ''O,
                                                 in Oct16 p_aes_sym_key,
                                                 out InnerAtResponse p_inner_at_response,
                                                 out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data
                                                 ) return boolean {
      // Local variables
      var bitstring v_msg_bit;
      var octetstring v_msg;
      var Oct12 v_nonce;
      var Ieee1609Dot2Data v_ieee1609dot2_signed_data;
      var EtsiTs103097Certificate v_at_certificate;
      var boolean p_result := false;

      log(">>> f_http_build_authorization_response: p_inner_at_request= ", p_inner_at_request);
      log(">>> f_http_build_authorization_response: p_responseCode= ", p_responseCode);
      log(">>> f_http_build_authorization_response: p_request_hash= ", p_request_hash);
      log(">>> f_http_build_authorization_response: p_private_key= ", p_private_key);
      log(">>> f_http_build_authorization_response: p_digest= ", p_digest);
      log(">>> f_http_build_authorization_response: p_aes_sym_key= ", p_aes_sym_key);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Check expectred response
      if (p_responseCode != ok) {
        p_inner_at_response := valueof(
                                       m_innerAtResponse_ko(
                                                            p_request_hash,
                                                            p_responseCode
                                                            )
                                       );
        p_result := true;
      } else {
        // Generate the certificate
        if (f_generate_at_certificate_for_inner_at_response(valueof(p_inner_at_request), p_private_key, p_digest, v_at_certificate) == false) {
          log("f_http_build_authorization_response: Failed to generate the certificate");
          p_inner_at_response := valueof(
                                         m_innerAtResponse_ko(
                                                              p_request_hash,
                                                              its_aa_incompleterequest
                                                              )
                                         );
        } else {
          p_inner_at_response := valueof(
                                         m_innerAtResponse_ok(
                                                              p_request_hash,
                                                              v_at_certificate
                                                              )
                                         );
        }
      }

      // Secure the response
      log("f_http_build_authorization_response: p_inner_at_response= ", p_inner_at_response);
      v_msg := bit2oct(encvalue(m_etsiTs102941Data_inner_at_response(p_inner_at_response)));
      v_nonce := substr(f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 16)), 0, 12); // Random value
      // TODO Consider  Sha384: m_signerIdentifier_digest(f_hashedId8FromSha384(p_digest))
      if (f_build_pki_secured_response_message(p_private_key,
                                               valueof(m_signerIdentifier_digest(f_hashedId8FromSha256(p_digest))),//  in SignerIdentifier p_signer_identifier,
                                               v_msg,
                                               p_aes_sym_key,
                                               v_nonce,
                                               p_ieee1609dot2_signed_and_encrypted_data
                                               ) == false) {
        log("f_http_build_authorization_response: Failed to generate the certificate");
        p_inner_at_response := valueof(
                                       m_innerAtResponse_ko(
                                                            p_request_hash,
                                                            its_aa_deniedpermissions
                                                            )
                                       );
      } else {
        p_result := true;
      }

      log("<<< f_http_build_authorization_response: p_result= ", p_result);
      log("<<< f_http_build_authorization_response: p_inner_at_response= ", p_inner_at_response);
      return p_result;
    } // End of function f_http_build_authorization_response
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_http_build_authorization_validation_request(
                                                           in InnerAtRequest p_inner_at_request,
                                                           in octetstring p_public_key_compressed,
                                                           in integer p_compressed_key_mode,
                                                           in octetstring p_private_enc_key,
                                                           in octetstring p_public_compressed_enc_key,
                                                           in integer p_compressed_enc_key_mode,
                                                           out Oct16 p_aes_sym_key,
                                                           out Oct16 p_encrypted_sym_key,
                                                           out Oct16 p_authentication_vector,
                                                           out Oct12 p_nonce,
                                                           out octetstring p_salt,
                                                           out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
                                                           out Oct32 p_request_hash
                                                           ) runs on ItsPkiHttp {
      // Local variables
      var AuthorizationValidationRequest v_authorization_validation_request;
      var bitstring v_authorization_validation_request_msg;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;

      log(">>> f_http_build_authorization_validation_request");

      // Copy the sharedAtRequest component from the InnerAtRequest received in the AuthorizationRequestMessage
      v_authorization_validation_request.sharedAtRequest := p_inner_at_request.sharedAtRequest;
      // Copy the ecSignature component from the InnerAtRequest received in the AuthorizationRequestMessage or AuthorizationRequestMessageWithPop
      v_authorization_validation_request.ecSignature := p_inner_at_request.ecSignature;
      // Secure the InnerAtRequest message
      if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("f_http_build_authorization_validation_request: Non canonical EA certificate");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("f_http_build_authorization_validation_request: Public encryption key: ", v_public_enc_key);
      log("f_http_build_authorization_validation_request: Public encryption key comp: ", v_compressed_enc_key_mode);
      p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3.
      log("f_http_build_authorization_validation_request: vc_aaHashedId8: ", vc_aaHashedId8);
      log("f_http_build_authorization_validation_request: p_salt: ", p_salt);
      if(f_build_pki_secured_request_message_signed_with_pop(vc_aaPrivateKey, valueof(m_signerIdentifier_digest(vc_aaHashedId8)), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_validation_request(v_authorization_validation_request))), PX_EC_ALG_FOR_ATV, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
        log("f_http_build_authorization_validation_request: Failed to generate Authorization Request");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("f_http_build_authorization_validation_request: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
      log("f_http_build_authorization_validation_request: p_request_hash= ", p_request_hash);
    } // End of function f_http_build_authorization_validation_request

    function f_http_build_invalid_authorization_validation_request(
                                                                   in InnerAtRequest p_inner_at_request,
                                                                   in octetstring p_public_key_compressed,
                                                                   in integer p_compressed_key_mode,
                                                                   in octetstring p_private_enc_key,
                                                                   in octetstring p_public_compressed_enc_key,
                                                                   in integer p_compressed_enc_key_mode,
                                                                   out Oct16 p_aes_sym_key,
                                                                   out Oct16 p_encrypted_sym_key,
                                                                   out Oct16 p_authentication_vector,
                                                                   out Oct12 p_nonce,
                                                                   out octetstring p_salt,
                                                                   out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
                                                                   out Oct32 p_request_hash
                                                                   ) runs on ItsPkiHttp {
      // Local variables
      var AuthorizationValidationRequest v_authorization_validation_request;
      var bitstring v_authorization_validation_request_msg;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;

      log(">>> f_http_build_invalid_authorization_validation_request");

      // Copy the sharedAtRequest component from the InnerAtRequest received in the AuthorizationRequestMessage
      v_authorization_validation_request.sharedAtRequest := p_inner_at_request.sharedAtRequest;
      // Copy the ecSignature component from the InnerAtRequest received in the AuthorizationRequestMessage or AuthorizationRequestMessageWithPop
      v_authorization_validation_request.ecSignature := p_inner_at_request.ecSignature;
      // Secure the InnerAtRequest message
      if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("f_http_build_invalid_authorization_validation_request: Non canonical EA certificate");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("f_http_build_invalid_authorization_validation_request: Public encryption key: ", v_public_enc_key);
      log("f_http_build_invalid_authorization_validation_request: Public encryption key comp: ", v_compressed_enc_key_mode);
      p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3.
      log("f_http_build_invalid_authorization_validation_request: vc_aaHashedId8: ", vc_aaHashedId8);
      log("f_http_build_invalid_authorization_validation_request: p_salt: ", p_salt);
      if(f_build_pki_secured_request_message_signed_with_pop(vc_aaPrivateKey, valueof(m_signerIdentifier_digest(vc_aaHashedId8)), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_authorization_validation_request(v_authorization_validation_request))), PX_EC_ALG_FOR_ATV, true, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash) == false) {
        log("f_http_build_invalid_authorization_validation_request: Failed to generate Authorization Request");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("f_http_build_invalid_authorization_validation_request: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
      log("f_http_build_invalid_authorization_validation_request: p_request_hash= ", p_request_hash);
    } // End of function f_http_build_invalid_authorization_validation_request

    function f_http_build_authorization_validation_response(
                                                            in SharedAtRequest p_shared_at_request,
                                                            in AuthorizationValidationResponseCode p_responseCode := ok,
                                                            in Oct16 p_request_hash,
                                                            in octetstring p_private_key := ''O,
                                                            in octetstring p_digest := ''O,
                                                            in Oct16 p_aes_sym_key,
                                                            out AuthorizationValidationResponse p_authorization_validation_response,
                                                            out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data
                                                            ) return boolean {
      // Local variables
      var bitstring v_msg_bit;
      var octetstring v_msg;
      var Oct12 v_nonce;
      var Ieee1609Dot2Data v_ieee1609dot2_signed_data;
      var EtsiTs103097Certificate v_at_certificate;
      var boolean p_result := false;

      log(">>> f_http_build_authorization_validation_response: p_shared_at_request= ", p_shared_at_request);
      log(">>> f_http_build_authorization_validation_response: p_responseCode= ", p_responseCode);
      log(">>> f_http_build_authorization_validation_response: p_request_hash= ", p_request_hash);
      log(">>> f_http_build_authorization_validation_response: p_private_key= ", p_private_key);
      log(">>> f_http_build_authorization_validation_response: p_digest= ", p_digest);
      log(">>> f_http_build_authorization_validation_response: p_aes_sym_key= ", p_aes_sym_key);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Check expectred response
      if (p_responseCode != ok) {
        p_authorization_validation_response := valueof(
                                                       m_authorizationValidationResponse_ko(
                                                                                            p_request_hash,
                                                                                            p_responseCode
                                                                                            )
                                                       );
        p_result := true;
      } else {
        p_authorization_validation_response := valueof(m_authorizationValidationResponse_ok(
                                                                                            p_request_hash,
                                                                                            p_shared_at_request.requestedSubjectAttributes
                                                                                            )
                                                        );
      }
      log("f_http_build_authorization_validation_response: p_authorization_validation_response= ", p_authorization_validation_response);
      // Encapsulte authorization validation response into EtsiTs102941Data
      v_msg := bit2oct(encvalue(m_etsiTs102941Data_authorization_validation_response(p_authorization_validation_response)));
      // Secure the response
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      v_nonce := substr(f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 16)), 0, 12); // Random value
      if (f_build_pki_secured_response_message(p_private_key,
                                               valueof(m_signerIdentifier_digest(f_hashedId8FromSha256(p_digest))),//  in SignerIdentifier p_signer_identifier,
                                               v_msg,
                                               p_aes_sym_key,
                                               v_nonce,
                                               p_ieee1609dot2_signed_and_encrypted_data
                                               ) == false) {
        log("f_http_build_authorization_validation_response: Failed to generate the certificate");
        p_authorization_validation_response := valueof(
                                                       m_authorizationValidationResponse_ko(
                                                                                            p_request_hash,
                                                                                            deniedpermissions
                                                                                            )
                                                       );
      } else {
        p_result := true;
      }
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log("<<< f_http_build_authorization_validation_response: p_result= ", p_result);
      log("<<< f_http_build_authorization_validation_response: p_authorization_validation_response= ", p_authorization_validation_response);
      return p_result;
    } // End of function f_http_build_authorization_validation_response


    function f_http_build_butterfly_authorization_request_message( // TODO Cleanup parameters
                                                                  out octetstring p_caterpillar_private_key,
                                                                  out octetstring p_caterpillar_public_key_compressed,
                                                                  out integer p_caterpillar_compressed_mode,
                                                                  out Oct16 p_aes_sym_key,
                                                                  out Oct16 p_encrypted_sym_key,
                                                                  out Oct16 p_authentication_vector,
                                                                  out Oct12 p_nonce,
                                                                  out octetstring p_salt,
                                                                  out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
                                                                  out Oct32 p_request_hash,
                                                                  out EeRaCertRequest p_ee_ra_cert_request
                                                                  ) runs on ItsPkiHttp {

      var Ieee1609Dot2Data v_ee_ra_cert_request_signed;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var octetstring v_private_key;
      var boolean v_result;

      log(">>> f_http_build_butterfly_authorization_request_message");

      // Generate EeRaCertRequest
      if (f_generate_ee_ra_cert_request(p_caterpillar_private_key, p_caterpillar_public_key_compressed, p_caterpillar_compressed_mode, p_ee_ra_cert_request) == false) {
        log("*** f_http_build_butterfly_authorization_request_message: ERROR: Failed to generate InnerEcRequest ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log ("f_http_build_butterfly_authorization_request_message: p_ee_ra_cert_request: ", p_ee_ra_cert_request);

      // Secure EeRaCertRequest
      if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_butterfly_authorization_request_message: ERROR: Non canonical EA certificate ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("f_http_build_butterfly_authorization_request_message: Public encryption key: ", v_public_enc_key);
      log("f_http_build_butterfly_authorization_request_message: Public encryption key comp: ", v_compressed_enc_key_mode);
      p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3.
      if (PX_VE_ALG == e_nist_p256) {
        v_private_key := PICS_ITS_S_SIGN_NITSP256_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_brainpool_p256_r1) {
        v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP256r1_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_sm2_p256) {
        v_private_key := PICS_ITS_S_SIGN_SM2P256_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_nist_p384) {
        v_private_key := PICS_ITS_S_SIGN_NISTP384_PRIVATE_KEY;
      } else {
        v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP384r1_PRIVATE_KEY;
      }
      v_result := f_build_pki_secured_request_message_signed_with_pop(v_private_key, valueof(m_signerIdentifier_self), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_ee_ra_cert_request(p_ee_ra_cert_request))), PX_EC_ALG_FOR_EC, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
      if (v_result == false) {
        log("*** f_http_build_butterfly_authorization_request_message: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      } else {
        log("f_http_build_butterfly_authorization_request_message: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
        log("f_http_build_butterfly_authorization_request_message: p_request_hash= ", p_request_hash);
      }
    } // End of function f_http_build_butterfly_authorization_request_message

    function f_http_build_butterfly_cert_response(
                                                  in HashedId8 p_request_hash,
                                                  in octetstring p_private_key := ''O,
                                                  in octetstring p_digest := ''O,
                                                  in Oct16 p_aes_sym_key,
                                                  out AcaRaCertResponse p_aca_ra_cert_response,
                                                  out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data
                                                  )  runs on ItsPkiHttp return boolean {
      // Local variables
      var bitstring v_msg_bit;
      var octetstring v_msg;
      var Oct12 v_nonce;
      var Ieee1609Dot2Data v_ieee1609dot2_signed_data;
      var EtsiTs103097Certificate v_at_certificate;
      var boolean v_result := false;

      log(">>> f_http_build_butterfly_cert_response: p_request_hash= ", p_request_hash);
      log(">>> f_http_build_butterfly_cert_response: p_private_key= ", p_private_key);
      log(">>> f_http_build_butterfly_cert_response: p_digest= ", p_digest);
      log(">>> f_http_build_butterfly_cert_response: p_aes_sym_key= ", p_aes_sym_key);

      p_aca_ra_cert_response := valueof(
                                        m_ra_aca_cert_response(
                                                               f_getCurrentTimeUtc(),
                                                               p_request_hash,
                                                               m_aca_response_plain(m_etsiTs103097Data_unsecured(''O)) // FIXME FSCOM
                                        ));

      // Secure the response
      log("f_http_build_butterfly_cert_response: p_aca_ra_cert_response= ", p_aca_ra_cert_response);
      v_msg := bit2oct(encvalue(m_etsiTs102941Data_aca_ra_cert_response(p_aca_ra_cert_response)));
      v_nonce := substr(f_hashWithSha256(int2oct((f_getCurrentTimeUtc() * 1000), 16)), 0, 12); // Random value
      // TODO Consider  Sha384: m_signerIdentifier_digest(f_hashedId8FromSha384(p_digest))
      if (f_build_pki_secured_response_message(p_private_key,
                                               valueof(m_signerIdentifier_digest(f_hashedId8FromSha256(p_digest))),//  in SignerIdentifier p_signer_identifier,
                                               v_msg,
                                               p_aes_sym_key,
                                               v_nonce,
                                               p_ieee1609dot2_signed_and_encrypted_data
                                               ) == false) {
        log("f_http_build_butterfly_cert_response: Failed to generate the certificate");
      } else {
        v_result := true;
      }

      log("<<< f_http_build_butterfly_cert_response: v_result= ", v_result);
      log("<<< f_http_build_butterfly_cert_response: p_aca_ra_cert_response= ", p_aca_ra_cert_response);
      return v_result;

    } // End of function f_http_build_butterfly_cert_response

    function f_http_build_butterfly_at_download_request_message(
                                                                in charstring p_filename,
                                                                out Oct16 p_aes_sym_key,
                                                                out Oct16 p_encrypted_sym_key,
                                                                out Oct16 p_authentication_vector,
                                                                out Oct12 p_nonce,
                                                                out octetstring p_salt,
                                                                out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
                                                                out Oct32 p_request_hash
                                                                ) runs on ItsPkiHttp {
      var EeRaDownloadRequest v_ee_ra_download_request;
      var Ieee1609Dot2Data v_ee_ra_download_request_signed;
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var octetstring v_private_key;
      var boolean v_result;

      log(">>> f_http_build_butterfly_at_download_request_message");

      // Generate EeRaDownloadRequest
      if (f_generate_ee_ra_download_request(p_filename, v_ee_ra_download_request) == false) {
        log("*** f_http_build_butterfly_at_download_request_message: ERROR: Failed to generate InnerEcRequest ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log ("f_http_build_butterfly_at_download_request_message: v_ee_ra_download_request: ", v_ee_ra_download_request);

      // Secure EeRaDownloadRequest
      if (f_extract_enc_key(vc_eaCertificate, v_public_enc_key, v_compressed_enc_key_mode) == false) {
        log("*** f_http_build_butterfly_at_download_request_message: ERROR: Non canonical EA certificate ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      log("f_http_build_butterfly_at_download_request_message: Public encryption key: ", v_public_enc_key);
      log("f_http_build_butterfly_at_download_request_message: Public encryption key comp: ", v_compressed_enc_key_mode);
      p_salt := vc_eaWholeHash256; // IEEE 1609.2: If the encryption key was obtained from a certificate c, P1 is SHA-256 (c), where c is the COER encoding of the certificate, canonicalized per 6.4.3.
      if (PX_VE_ALG == e_nist_p256) {
        v_private_key := PICS_ITS_S_SIGN_NITSP256_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_brainpool_p256_r1) {
        v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP256r1_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_sm2_p256) {
        v_private_key := PICS_ITS_S_SIGN_SM2P256_PRIVATE_KEY;
      } else if (PX_VE_ALG == e_nist_p384) {
        v_private_key := PICS_ITS_S_SIGN_NISTP384_PRIVATE_KEY;
      } else {
        v_private_key := PICS_ITS_S_SIGN_BRAINPOOLP384r1_PRIVATE_KEY;
      }
      v_result := f_build_pki_secured_request_message_signed_with_pop(v_private_key, valueof(m_signerIdentifier_self), vc_eaHashedId8/*recipientId*/, v_public_enc_key, v_compressed_enc_key_mode, p_salt, bit2oct(encvalue(m_etsiTs102941Data_ee_ra_download_request(v_ee_ra_download_request))), PX_EC_ALG_FOR_EC, -, p_ieee1609dot2_signed_and_encrypted_data, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, p_request_hash);
      if (v_result == false) {
        log("*** f_http_build_butterfly_at_download_request_message: ERROR: Failed to generate InnerEcRequestSignedForPop ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      } else {
        log("f_http_build_butterfly_at_download_request_message: p_ieee1609dot2_signed_and_encrypted_data= ", p_ieee1609dot2_signed_and_encrypted_data);
        log("f_http_build_butterfly_at_download_request_message: p_request_hash= ", p_request_hash);
      }
    } // End of function f_http_build_butterfly_at_download_request_message

ASN.1 Documenter's avatar
ASN.1 Documenter committed
    function f_http_build_dc_request( // TODO Cleanup parameters
                                     in charstring p_ea_certificate_id,
                                     in charstring p_aa_certificate_id,
                                     in charstring p_rca_certificate_id,
                                     out octetstring p_private_key,
                                     out octetstring p_public_key_compressed,
                                     out integer p_compressed_mode,
                                     out Oct16 p_aes_sym_key,
                                     out Oct16 p_encrypted_sym_key,
                                     out Oct16 p_authentication_vector,
                                     out Oct12 p_nonce,
                                     out octetstring p_salt,
                                     out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
                                     out Oct32 p_request_hash
                                     ) runs on ItsPkiHttp {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
    } // End of function 
  } // End of group http

  group generate_certificates {

    function f_generate_ec_certificate(
                                       out octetstring p_private_key,
                                       out Certificate p_ec_certificate
                                       ) return boolean {
      var octetstring v_public_key_x;
      var octetstring v_public_key_y;
      var octetstring p_public_key_compressed;
      var integer p_compressed_mode;
      var EccP256CurvePoint v_ecc_p256_curve_point;
      var SequenceOfPsidSsp v_appPermissions := { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs
        valueof(m_appPermissions(36, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_CAM })),
        valueof(m_appPermissions(37, { bitmapSsp := PX_INNER_EC_CERTFICATE_BITMAP_SSP_DENM }))
      };
      var template (value) EtsiTs103097Certificate v_cert;
      var bitstring v_tbs;
      var Oct32 v_sig;
      var bitstring v_enc_msg;
      var PublicVerificationKey v_public_verification_key;
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      log(">>> f_generate_ec_certificate");
      log("f_generate_ec_certificate: PX_EC_ALG_FOR_EC=", PX_EC_ALG_FOR_EC);
      log("f_generate_ec_certificate: PX_VE_ALG=", PX_VE_ALG);
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      // Generate verification keys for the certificate
      if (f_generate_key_pair(p_private_key, v_public_key_x, v_public_key_y, p_public_key_compressed, p_compressed_mode) == false) {
        log("f_generate_ec_certificate: Failed to generate verification key");
        return false;
      }
      if (p_compressed_mode == 0) {
        v_ecc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(p_public_key_compressed));
      } else {
        v_ecc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(p_public_key_compressed));
      }

      if (PX_EC_ALG_FOR_EC == e_nist_p256) {
        v_public_verification_key := valueof(
                                             m_publicVerificationKey_ecdsaNistP256(
                                                                                   v_ecc_p256_curve_point
                                                                                   ));
      } else if (PX_EC_ALG_FOR_EC == e_nist_p384) { // FIXME FSCOM
        // v_public_verification_key := valueof(
        //                                      m_publicVerificationKey_ecdsaNistP384(
        //                                                                            v_ecc_p384_curve_point
        //                                                                            ));
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } else if (PX_EC_ALG_FOR_EC == e_brainpool_p256_r1) {
        v_public_verification_key := valueof(
                                             m_publicVerificationKey_ecdsaBrainpoolP256r1(
                                                                                          v_ecc_p256_curve_point
                                                                                          ));
      } else if (PX_EC_ALG_FOR_EC == e_brainpool_p384_r1) { // FIXME FSCOM
        // v_public_verification_key := valueof(
        //                                      m_publicVerificationKey_ecdsaBrainpoolP384r1(
        //                                                                                   v_ecc_p384_curve_point
        //                                                                                   ));
      } else if (PX_EC_ALG_FOR_EC == e_sm2_p256) { // FIXME FSCOM
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } else {
        log("f_generate_ec_certificate: Wrong encryption algorithm, check PX_EC_ALG_FOR_xx");
        return false;
      }
      v_cert := m_etsiTs103097Certificate(
                                          m_issuerIdentifier_sha256AndDigest(f_hashedId8FromSha256(f_hashWithSha256('616263'O))),
                                          m_toBeSignedCertificate_at(
                                                                     v_appPermissions,
                                                                     m_verificationKeyIndicator_verificationKey(
                                                                                                                v_public_verification_key
                                                                                                                ),
                                                                     m_validityPeriod(
                                                                                      f_getCurrentTime() / 1000,
                                                                                      m_duration_in_hours(PX_GENERATED_CERTIFICATE_DURATION)
                                                                                      ),
                                                                     m_geographicRegion_identifiedRegion(
                                                                                                         {
                                                                                                           m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2),
                                                                                                           m_identifiedRegion_country_only(PX_GENERATED_CERTIFICATE_REGION_COUNTRY_2)
                                                                                                           }
                                                                                                         ),
                                                                     PX_GENERATED_CERTIFICATE_SUBJECT_ASSURENCE_LEVEL
                                                                     )
                                          );
      // Encode it ==> Get octetstring
      v_tbs := encvalue(v_cert.toBeSigned);
      // Sign the certificate
      v_sig := f_signWithEcdsa(bit2oct(v_tbs), int2oct(11, 32), p_private_key);
      if (PX_VE_ALG == e_nist_p256) {
ASN.1 Documenter's avatar
ASN.1 Documenter committed
        v_cert.signature_ := m_signature_ecdsaNistP256(
                                                       m_ecdsaP256Signature(
                                                                            m_eccP256CurvePoint_x_only(
                                                                                                       substr(v_sig, 0, 32)
                                                                                                       ),
                                                                            substr(v_sig, 32, 32)
                                                                            )
                                                       );
      } else if (PX_VE_ALG == e_brainpool_p256_r1) { // FIXME FSCOM
        v_cert.signature_ := m_signature_ecdsaBrainpoolP256r1(
                                                              m_ecdsaP256Signature(
                                                                                    m_eccP256CurvePoint_x_only(
                                                                                                              substr(v_sig, 0, 32)
                                                                                                              ),
                                                                                    substr(v_sig, 32, 32)
                                                                                    )
                                                              );
      } else if (PX_VE_ALG == e_sm2_p256) { // FIXME FSCOM
      } else if (PX_VE_ALG == e_nist_p384) {
        v_cert.signature_ := m_signature_ecdsaNistP384(
                                                       m_ecdsaP384Signature(
                                                                            m_eccP384CurvePoint_x_only(
                                                                                                       substr(v_sig, 0, 48)
                                                                                                       ),
                                                                             substr(v_sig, 48, 48)
                                                                             )
                                                        );
ASN.1 Documenter's avatar
ASN.1 Documenter committed
      } else if (PX_VE_ALG == e_brainpool_p384_r1) {
        v_cert.signature_ := m_signature_ecdsaBrainpoolP384r1(
                                                              m_ecdsaP384Signature(