Commit 4bca0b49 authored by Yann Garcia's avatar Yann Garcia
Browse files

Fisrt implementation of BFK TPs done

parent 765dffb3
Loading
Loading
Loading
Loading
+2644 −1419

File changed.

Preview size limit exceeded, changes collapsed.

+5 −0
Original line number Diff line number Diff line
@@ -142,6 +142,11 @@ module LibItsPki_Pics {
   */
  modulepar charstring PICS_HTTP_POST_URI_EC := "/enrolment";
  
  /**
   * @desc HTTP POST URI for BFK Authorization request
   */
  modulepar charstring PICS_HTTP_POST_URI_BFK_EC := "/enrolment";
  
  /**
   * @desc HTTP POST URI for InnerATRequest
   */
+494 −51

File changed.

Preview size limit exceeded, changes collapsed.

Compare ace77678 to 021805f1
Original line number Diff line number Diff line
Subproject commit ace776783be6ef49438d798d59e7346822df3b60
Subproject commit 021805f17253f5b0baf80b13bca8151a05342655
+519 −238
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@ module LibItsPki_Functions {
  import from EtsiTs102941MessagesCa language "ASN.1:1997" all;
  import from EtsiTs102941TrustLists language "ASN.1:1997" all;
  import from EtsiTs103097Module language "ASN.1:1997" all;
  import from Ieee1609Dot2Dot1EeRaInterface language "ASN.1:1997" all;
  import from Ieee1609Dot2Dot1AcaRaInterface language "ASN.1:1997" all;
  import from Ieee1609Dot2Dot1Acpc language "ASN.1:1997" all;
  import from ETSI_ITS_CDD language "ASN.1:1997" all;
  import from CAM_PDU_Descriptions language "ASN.1:1997" all;

@@ -794,6 +797,24 @@ module LibItsPki_Functions {
            p_http_message.response.header := p_headers;
          }
          httpAtPort.send(p_http_message);
        } else if (v_content_text == { "bfk_auth_request" }) {
          log("f_http_send: Send on EC end point");
          f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_EC }, p_headers);
          if (ischosen(p_http_message.request)) {
            p_http_message.request.header := p_headers;
          } else {
            p_http_message.response.header := p_headers;
          }
          httpEcPort.send(p_http_message);
        } else if (v_content_text == { "bfk_at_download_request" }) {
          log("f_http_send: Send on EC end point");
          f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_EC }, p_headers);
          if (ischosen(p_http_message.request)) {
            p_http_message.request.header := p_headers;
          } else {
            p_http_message.response.header := p_headers;
          }
          httpEcPort.send(p_http_message);
        } else if (v_content_text == { "ca_request" }) {
          log("f_http_send: Send on CA end point");
          f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_CA }, p_headers);
@@ -911,7 +932,7 @@ module LibItsPki_Functions {

  } // End of group helpers

  group http { // TODO Split into EnnerEc, Authorization & AuthorizationValidation
  group http { // TODO Split into EnnerEc, Authorization, AuthorizationValidation and bfk

    function f_http_build_inner_ec_request( // TODO Cleanup parameters
                                           out octetstring p_private_key,
@@ -943,7 +964,7 @@ module LibItsPki_Functions {
      log ("f_http_build_inner_ec_request: ==> EC verification private key: ", p_private_key);
      log ("f_http_build_inner_ec_request: ==> EC verification public compressed key: ", p_public_key_compressed);
      log ("f_http_build_inner_ec_request: ==> EC verification public compressed mode: ", p_compressed_mode);
      // TODO Store enrolment keys for re-enrolment
      // Store enrolment keys for re-enrolment
      vc_ec_private_keys[vc_ec_keys_counter] := p_private_key;
      vc_ec_public_compressed_key[vc_ec_keys_counter] := p_public_key_compressed;
      vc_ec_compressed_modes[vc_ec_keys_counter] := p_compressed_mode;
@@ -1678,6 +1699,171 @@ module LibItsPki_Functions {
      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

    function f_http_build_dc_request( // TODO Cleanup parameters
                                     in charstring p_ea_certificate_id,
                                     in charstring p_aa_certificate_id,
@@ -3262,6 +3448,103 @@ module LibItsPki_Functions {

  } // End of group inner_at_xxx

  group bfk {

    function f_generate_ee_ra_cert_request(
                                           out octetstring p_caterpillar_private_key,
                                           out octetstring p_caterpillar_public_key_compressed,
                                           out integer p_caterpillar_compressed_mode,
                                           out EeRaCertRequest p_ee_ra_cert_request
                                           ) runs on ItsPkiHttp return boolean {
      var octetstring v_public_key_x;
      var octetstring v_public_key_y;
      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 PublicVerificationKey v_public_verification_key;
      var template (value) ToBeSignedCertificate v_tbs;
      log (">>> f_generate_ee_ra_cert_request");
      log("f_generate_ee_ra_cert_request: PX_VE_ALG=", PX_VE_ALG);

      // Generate caterpillar keys
      if (f_generate_key_pair(p_caterpillar_private_key, v_public_key_x, v_public_key_y, p_caterpillar_public_key_compressed, p_caterpillar_compressed_mode) == false) {
        log("f_generate_ee_ra_cert_request: Failed to generate caterpillar keys");
        return false;
      }
      log ("f_generate_ee_ra_cert_request: Caterpillar private key: ", p_caterpillar_private_key);
      log ("f_generate_ee_ra_cert_request: Caterpillar public compressed key: ", p_caterpillar_public_key_compressed);
      log ("f_generate_ee_ra_cert_request: Caterpillar public compressed mode: ", p_caterpillar_compressed_mode);
      if (p_caterpillar_compressed_mode == 0) {
        v_ecc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(p_caterpillar_public_key_compressed));
      } else {
        v_ecc_p256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(p_caterpillar_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
        //                                                                            ));
      } 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
      } else {
        log("f_generate_ee_ra_cert_request: Wrong encryption algorithm, check PX_EC_ALG_FOR_xx");
        return false;
      }

      v_tbs := m_bfk_to_be_signed_certificate(
                                              { none_ := NULL },
                                              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
                                              );
      p_ee_ra_cert_request := valueof(m_butterfly_authorization_request(f_getCurrentTime(), explicit, v_tbs));
      log("f_generate_ee_ra_cert_request: p_ee_ra_cert_request: ", p_ee_ra_cert_request);

      return true;
    } // End of function f_generate_ee_ra_cert_request

    function f_generate_ee_ra_download_request(
                                               in charstring p_filename,
                                               out EeRaDownloadRequest p_ee_ra_download_request
                                               ) runs on ItsPkiHttp return boolean {
      p_ee_ra_download_request := valueof(m_ee_ra_download_request(f_getCurrentTimeUtc(), p_filename));
      
      log("f_generate_ee_ra_download_request: p_ee_ra_download_request: ", p_ee_ra_download_request);

      return true
    } // End of function f_generate_ee_ra_download_request

  } // End of group bfk

  group dc {

    function f_build_dc(
@@ -4650,8 +4933,6 @@ module LibItsPki_Functions {
      } else {
        var charstring v_certificate_id;
        var octetstring v_hash;
        // FIXME Huge issue, certificate is BP256 and PX_VE_ALG is e_brainpool_p384_r1, so v_hash & p_private_key are 32 bytes length not 48
        // ==> Need to sign with v_certificate_id capabilities not with PX_VE_ALG :(
        fx_readCertificateFromDigest(p_signer_identifier.digest, v_certificate_id); // TODO Add a wrapper function
        f_getCertificateHash(v_certificate_id, v_hash);
        v_tbs_signed := f_signWithEcdsa(bit2oct(encvalue(v_tbs)), v_hash, p_private_key);