Skip to content
LibItsPki_Functions.ttcn 137 KiB
Newer Older
                                                                                       m_eccP256CurvePoint_x_only(
                                                                                                                  substr(v_tbs_signed, 0, 32)
                                                                                                                  ),
                                                                                       substr(v_tbs_signed, 32, 32)
                                                                                       )
                                                                  )
                                 );
        } else if (ischosen(p_ec_certificate.signature_.ecdsaNistP256Signature)) {
          v_tbs_signed := f_signWithEcdsaNistp256WithSha256(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
          v_signature := valueof(
                                 m_signature_ecdsaNistP256(
                                                           m_ecdsaP256Signature(
                                                                                m_eccP256CurvePoint_x_only(
                                                                                                           substr(v_tbs_signed, 0, 32)
                                                                                                           ),
                                                                                substr(v_tbs_signed, 32, 32)
                                                                                )
                                                           )
                                 );
        } else {
          // Error
          log("f_generate_inner_at_request: Failed to process signature");
          return false;
        }
      v_signed_ec_signature := valueof(
                                       m_etsiTs103097Data_signed(
                                                                 m_signedData(
                                                                              m_signerIdentifier_digest(v_ec_hashed_id8), // Signer is thehasheId8 of the EC certificate obtained from Enrolment request
      log("f_generate_inner_at_request: v_signed_ec_signature= ", v_signed_ec_signature);
      
      if (PICS_ITS_S_WITH_PRIVACY) { // Build EtsiTs102097Data-Encrypted structure
        var octetstring v_public_enc_key;
        var integer v_compressed_mode;
        var Oct12 v_nonce;
        var Oct16 v_authentication_vector;
        var Oct16 v_aes_sym_key;
        var Oct16 v_encrypted_sym_key;
        var HashedId8 v_recipientId;
        var octetstring v_public_compressed_ephemeral_key;
        var integer v_public_compressed_ephemeral_mode;
        var octetstring v_enc_signed_ec_signature;
        var EncryptedDataEncryptionKey v_encrypted_data_encryption_key;

        // Use EA certificate for the encryption
        if (PX_EC_ALG == e_nist_p256) {
          if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0)) {
            v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0;
            v_compressed_mode := 0;
          } else if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1)) {
            v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1;
            v_compressed_mode := 1;
          } else {
            log("f_generate_inner_at_request: Wrong NistP256 encryption variant");
            return false;
          }
Yann Garcia's avatar
Yann Garcia committed
          if (PX_EC_ALG == e_nist_p256) {
            v_enc_signed_ec_signature := f_encryptWithEciesNistp256WithSha256(bit2oct(encvalue(v_signed_ec_signature)), v_public_enc_key, v_compressed_mode, ''O, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, PICS_SEC_FIXED_KEYS);
          } else if (PX_EC_ALG == e_brainpool_p256_r1) {
            v_enc_signed_ec_signature := f_encryptWithEciesBrainpoolp256WithSha256(bit2oct(encvalue(v_signed_ec_signature)), v_public_enc_key, v_compressed_mode, ''O, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, PICS_SEC_FIXED_KEYS);
          } else {
            log("f_generate_inner_at_request: Wrong encryption variant");
            return false;
          }
          v_encrypted_data_encryption_key := valueof(
                                                     m_encryptedDataEncryptionKey_eciesNistP256(
                                                                                                m_evciesP256EncryptedKey(
                                                                                                                         v_eccP256_curve_point,
                                                                                                                         v_encrypted_sym_key,
                                                                                                                         v_authentication_vector
                                                                                                                         )));
        } else if (PX_EC_ALG == e_brainpool_p256_r1) {
          if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0)) {
            v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0;
            v_compressed_mode := 0;
          } else if (ischosen(p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1)) {
            v_public_enc_key := p_ea_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1;
            v_compressed_mode := 1;
          } else {
            log("f_generate_inner_at_request: Wrong BrainpoolP256r1 encryption variant");
            return false;
          }
Yann Garcia's avatar
Yann Garcia committed
          if (PX_EC_ALG == e_nist_p256) {
            v_enc_signed_ec_signature := f_encryptWithEciesNistp256WithSha256(bit2oct(encvalue(v_signed_ec_signature)), v_public_enc_key, v_compressed_mode, ''O, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, PICS_SEC_FIXED_KEYS);
          } else if (PX_EC_ALG == e_brainpool_p256_r1) {
            v_enc_signed_ec_signature := f_encryptWithEciesBrainpoolp256WithSha256(bit2oct(encvalue(v_signed_ec_signature)), v_public_enc_key, v_compressed_mode, ''O, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, PICS_SEC_FIXED_KEYS);
          } else {
            log("f_generate_inner_at_request: Wrong encryption variant");
            return false;
          }
          v_encrypted_data_encryption_key := valueof(
                                                     m_encryptedDataEncryptionKey_eciesBrainpoolP256r1(
                                                                                                       m_evciesP256EncryptedKey(
                                                                                                                                v_eccP256_curve_point,
                                                                                                                                v_encrypted_sym_key,
                                                                                                                                v_authentication_vector
                                                                                                                                )));
garciay's avatar
garciay committed
        } else {
          log("f_generate_inner_at_request: Wrong encryption variant");
garciay's avatar
garciay committed
          return false;
        }
        v_recipientId := p_ea_hashed_id8; // RecipientId is the HashedId8 of the EA certificate
        log("v_recipientId= ", v_recipientId);
        // Fill Certificate template with the public compressed keys (canonical form)
        if (v_public_compressed_ephemeral_mode == 0) {
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key));
          v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key));
        }
        p_inner_at_request.ecSignature := valueof(
                                                  m_ec_signature(
                                                                 m_etsiTs103097Data_encrypted(
                                                                                              m_encryptedData(
                                                                                                              {
                                                                                                                m_recipientInfo_signedDataRecipInfo(
                                                                                                                                                    m_pKRecipientInfo(
                                                                                                                                                                      v_recipientId,
                                                                                                                                                                      
                                                                                                                                                                      v_encrypted_data_encryption_key                                                                                                                                                            ))
                                                                                                                },
                                                                                                              m_SymmetricCiphertext_aes128ccm(
                                                                                                                                              m_aesCcmCiphertext(
                                                                                                                                                                 v_enc_signed_ec_signature
                                                                                                                                                                 )
                                                                                                                                              )
                                                                                                              )
      } else { // Skip the encryption, alowed to be re-identified by the AA
        p_inner_at_request.ecSignature := valueof(m_ec_signature_ext_payload(v_signed_ec_signature));
      }
      // Build the InnerAtRequest, EcSignature field is already set
      if (p_compressed_key_mode == 0) {
Yann Garcia's avatar
Yann Garcia committed
        v_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_0(v_public_key_x);
Yann Garcia's avatar
Yann Garcia committed
        v_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_1(v_public_key_x);
      }
      if (p_compressed_enc_key_mode == 0) {
Yann Garcia's avatar
Yann Garcia committed
        v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_0(v_public_enc_key_x);
Yann Garcia's avatar
Yann Garcia committed
        v_enc_eccP256_curve_point := m_eccP256CurvePoint_compressed_y_1(v_public_enc_key_x);
      }
      p_inner_at_request.publicKeys := valueof( // The freshly generated public keys to be used for the requested AT certificate
                                               m_publicKeys(
                                                            m_publicVerificationKey_ecdsaNistP256(
                                                                                                  v_eccP256_curve_point
                                                                                                  ),
                                                            m_encryptionKey( // FIXME Encryption keys could be optional
                                                                            -,
                                                                            m_publicEncryptionKey_ecdsaNistP256(v_enc_eccP256_curve_point)
                                                                             )
                                                            )
                                                );
      p_inner_at_request.hmacKey := v_hmac_key;
      log("p_inner_at_request= ", p_inner_at_request);
      
      return true;
    } // End of function f_generate_inner_at_request
    
    function f_generate_inner_at_response(
                                          in octetstring p_authorization_request_hash,
                                          in EtsiTs103097Certificate p_certificate,
                                          out InnerAtResponse p_authorization_response
                                          ) return boolean {
      // Local variables
      // Build the Proof of Possession InnerEcResponse
      p_authorization_response := valueof(
                                          m_innerAtResponse_ok(
                                                               substr(p_authorization_request_hash, 0, 16),
                                                               p_certificate
      
      return true;
    } // End of function f_generate_inner_at_response
    
  } // End of group inner_at_xxx
  
  group authorization_validation_xxx {
    
  } // End of group authorization_validation_xxx
  
  group awaiting_messages {
    
Yann Garcia's avatar
Yann Garcia committed
    function f_http_send(
                         in HeaderLines p_headers,
                         in template (value) HttpMessage p_http_message
                         ) runs on ItsPkiHttp {
      if (not(PICS_MULTIPLE_END_POINT)) {
        httpPort.send(p_http_message);
      } else {
        var charstring_list v_content_text;
        
        f_get_header(p_headers, c_header_content_text, v_content_text);
        
        if (not(isvalue(v_content_text))) {
          log("f_http_send: Failed to send message: header not found: ", c_header_content_text);
          return;
        }
        if (v_content_text == { "inner_ec_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 == { "inner_atv_request" }) {
          log("f_http_send: Send on ATV end point");
          f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_ATV }, p_headers);
          if (ischosen(p_http_message.request)) {
            p_http_message.request.header := p_headers;
          } else {
            p_http_message.response.header := p_headers;
          }
          httpAtVPort.send(p_http_message);
        } else if (v_content_text == { "inner_at_request" }) {
          log("f_http_send: Send on AT end point");
          f_set_headers_list({ c_header_host }, { PICS_HEADER_HOST_AT }, p_headers);
          if (ischosen(p_http_message.request)) {
            p_http_message.request.header := p_headers;
          } else {
            p_http_message.response.header := p_headers;
          }
          httpAtPort.send(p_http_message);
        } else {
          log("f_http_send: Invalid header value: ", v_content_text);
        }
      }
    } // End of function f_http_send
    
    function f_await_http_inner_ec_request_response(
Yann Garcia's avatar
Yann Garcia committed
                                                    out Oct32 p_private_key,
                                                    out Oct32 p_compressed_public_key,
                                                    out integer p_compressed_mode,
                                                    out InnerEcResponse p_inner_ec_response
                                                    ) runs on ItsPkiHttp return boolean {
      var HeaderLines v_headers;
      var Oct32 v_request_hash;
      var Oct16 v_encrypted_sym_key;
      var Oct16 v_aes_sym_key;
      var Oct16 v_authentication_vector;
      var Oct12 v_nonce;
      var octetstring v_salt;
      var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
      var EtsiTs102941Data v_etsi_ts_102941_data;
      var HttpMessage v_response;
Yann Garcia's avatar
Yann Garcia committed

      log(">>> f_await_http_inner_ec_request_response");
      f_http_build_inner_ec_request(p_private_key, p_compressed_public_key, p_compressed_mode, v_aes_sym_key, v_encrypted_sym_key, v_authentication_vector, v_nonce, v_salt, v_ieee1609dot2_signed_and_encrypted_data, v_request_hash);
      f_init_default_headers_list(-, "inner_ec_request", v_headers);
Yann Garcia's avatar
Yann Garcia committed
      f_http_send(
                  v_headers, 
                  m_http_request(
                                 m_http_request_post(
                                                     PICS_HTTP_POST_URI_EC,
                                                     v_headers,
                                                     m_http_message_body_binary(
                                                                                m_binary_body_ieee1609dot2_data(
                                                                                                                v_ieee1609dot2_signed_and_encrypted_data
                                                                                                                )))));
      tc_ac.start;
      alt {
Yann Garcia's avatar
Yann Garcia committed
        [not(PICS_MULTIPLE_END_POINT)] httpPort.receive(
                                                        mw_http_response(
                                                                         mw_http_response_ok(
                                                                                             mw_http_message_body_binary(
                                                                                                                         mw_binary_body_ieee1609dot2_data(
                                                                                                                                                          mw_enrolmentResponseMessage(
                                                                                                                                                                                      mw_encryptedData(
                                                                                                                                                                                                       -,
                                                                                                                                                                                                       mw_SymmetricCiphertext_aes128ccm
                                                                                                                                                                                                       ))))))) -> value v_response {
          tc_ac.stop;
          if (f_verify_pki_message(p_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, vc_eaCertificate, v_response.response.body.binary_body.ieee1609dot2_data, false, v_etsi_ts_102941_data) == false) {
            log("f_await_http_inner_ec_request_response: Failed to verify PKI message ***");
          } else {
            log("f_await_http_inner_ec_request_response: Receive ", v_etsi_ts_102941_data, " ***");
Yann Garcia's avatar
Yann Garcia committed
            // Verify the received EC certificate
            log("f_await_http_inner_ec_request_response: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec, -)))), " ***"); // TODO In TITAN, this is the only way to get the unmatching in log
            if (match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec, -))))) {
Yann Garcia's avatar
Yann Garcia committed
              p_inner_ec_response := v_etsi_ts_102941_data.content.enrolmentResponse;
              if (f_verify_ec_certificate(v_etsi_ts_102941_data.content.enrolmentResponse.certificate, vc_eaCertificate, p_compressed_public_key, p_compressed_mode)) {
Yann Garcia's avatar
Yann Garcia committed
                log("f_await_http_inner_ec_request_response: Well-secured EA certificate received ***");
                log("p_inner_ec_response= ", p_inner_ec_response);
                return true;
              } else {
                log("f_await_http_inner_ec_request_response: Cannot verify EC certificate signature ***");
Yann Garcia's avatar
Yann Garcia committed
                return true; // For debug mode only
Yann Garcia's avatar
Yann Garcia committed
              }
            } else {
              log("f_await_http_inner_ec_request_response: Unexpected message received ***");
            }
          }
        }
Yann Garcia's avatar
Yann Garcia committed
        [PICS_MULTIPLE_END_POINT] httpEcPort.receive(
                                                     mw_http_response(
                                                                      mw_http_response_ok(
                                                                                          mw_http_message_body_binary(
                                                                                                                      mw_binary_body_ieee1609dot2_data(
                                                                                                                                                       mw_enrolmentResponseMessage(
                                                                                                                                                                                   mw_encryptedData(
                                                                                                                                                                                                    -,
                                                                                                                                                                                                    mw_SymmetricCiphertext_aes128ccm
                                                                                                                                                                                                    ))))))) -> value v_response {
          tc_ac.stop;
          
Yann Garcia's avatar
Yann Garcia committed
          if (f_verify_pki_message(p_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, vc_eaCertificate, v_response.response.body.binary_body.ieee1609dot2_data, false, v_etsi_ts_102941_data) == false) {
            log("f_await_http_inner_ec_request_response: Failed to verify PKI message ***");
          } else {
            log("f_await_http_inner_ec_request_response: Receive ", v_etsi_ts_102941_data, " ***");
            // Verify the received EC certificate
            log("f_await_http_inner_ec_request_response: match ", match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec, -)))), " ***"); // TODO In TITAN, this is the only way to get the unmatching in log
            if (match(v_etsi_ts_102941_data.content, mw_enrolmentResponse(mw_innerEcResponse_ok(substr(v_request_hash, 0, 16), mw_etsiTs103097Certificate(-, mw_toBeSignedCertificate_ec, -))))) {
              p_inner_ec_response := v_etsi_ts_102941_data.content.enrolmentResponse;
              if (f_verify_ec_certificate(v_etsi_ts_102941_data.content.enrolmentResponse.certificate, vc_eaCertificate, p_compressed_public_key, p_compressed_mode)) {
                log("f_await_http_inner_ec_request_response: Well-secured EA certificate received ***");
                log("p_inner_ec_response= ", p_inner_ec_response);
                return true;
              } else {
                log("f_await_http_inner_ec_request_response: Cannot verify EC certificate signature ***");
                return true; // For debug mode only
              }
            } else {
              log("f_await_http_inner_ec_request_response: Unexpected message received ***");
            }
          }
        }
        [] tc_ac.timeout {
          log("f_await_http_inner_ec_request_response: Expected message not received ***");
        }
      } // End of 'alt' statement
      
      return false;
    } // End of function f_await_http_inner_ec_request_response
    
  } // End of group awaiting_messages
  
garciay's avatar
garciay committed
  group pki_functions {
     * @desc Build a signed and encrypted PKI request message
     * @param p_private_key         Private key for signature
     * @param p_signer_identifier   Signer identifier for signature, could be self or certificate HashedId8
     * @param p_recipientId         Recipient identifier to be inclued in encrypted layer.
     *                              If value is int2oct(0. 8), the recipient id is the HashedId8 of the symmetric key used by the sender to encrypt the message to which the response is built
     * @param p_public_key_compressed The public compressed key (canonical form) for encryption
     * @param p_compressed_mode      The compressed mode of the public compressed key (canonical form) for encryption
     * @param p_pki_message         The PKI message to be secured
     * @param p_ieee1609dot2_signed_and_encrypted_data The secured message
     * @return true on success, false otherwise
     */
    function f_build_pki_secured_request_message_signed_with_pop(
                                                                 in octetstring p_private_key,
                                                                 in SignerIdentifier p_signer_identifier,
                                                                 in HashedId8 p_recipientId,
                                                                 in octetstring p_public_key_compressed,
                                                                 in integer p_compressed_mode,
                                                                 in octetstring p_salt,
                                                                 in octetstring p_pki_message,
                                                                 out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
                                                                 out Oct16 p_aes_sym_key,
                                                                 out Oct16 p_encrypted_sym_key,
                                                                 out Oct16 p_authentication_vector,
                                                                 out Oct12 p_nonce,
                                                                 out Oct32 p_request_hash
                                                                 ) return boolean {
garciay's avatar
garciay committed
      // Local variables
      var template (value) EccP256CurvePoint v_eccP256_curve_point;
      var template (value) ToBeSignedData v_tbs;
      var Signature v_signature;
Yann Garcia's avatar
Yann Garcia committed
      var template (value) Ieee1609Dot2Data v_ieee1609dot2_signed_data;
      var octetstring v_encoded_request;
      var octetstring v_public_compressed_ephemeral_key;
      var integer v_public_compressed_ephemeral_mode;
      var octetstring v_encrypted_request;
      var EncryptedDataEncryptionKey v_encrypted_data_encryption_key;
Yann Garcia's avatar
Yann Garcia committed
      var bitstring v_enc_value;

      log(">>> f_build_pki_secured_request_message_signed_with_pop");
      // Signed the encoded PKI message
Yann Garcia's avatar
Yann Garcia committed
      v_tbs := m_toBeSignedData(
                                m_signedDataPayload(
garciay's avatar
garciay committed
                                                    m_etsiTs103097Data_unsecured(p_pki_message)
Yann Garcia's avatar
Yann Garcia committed
                                                   ),
                                m_headerInfo_inner_ec_request(c_its_aid_SCR, f_getCurrentTimeUtc())
Yann Garcia's avatar
Yann Garcia committed
                               );
Yann Garcia's avatar
Yann Garcia committed
      log("f_build_pki_secured_request_message_signed_with_pop: signer: ", p_signer_identifier);
      if (ischosen(p_signer_identifier.self_)) {
        v_tbs_signed := f_signWithEcdsa(bit2oct(encvalue(v_tbs)), int2oct(0, 32), p_private_key);
      } else {
        var charstring v_certificate_id;
        var octetstring v_hash;
        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);
      }
      // Add the signature and create EtsiTs103097Data-Signed data structure
      if (PX_VE_ALG == e_nist_p256) {
       v_signature := valueof(
                              m_signature_ecdsaNistP256(
                                                        m_ecdsaP256Signature(
                                                                             m_eccP256CurvePoint_x_only(
                                                                                                        substr(v_tbs_signed, 0, 32)
                                                                                                        ),
                                                                             substr(v_tbs_signed, 32, 32)
                                                                             )
                                                        )
                              );
      } else if (PX_VE_ALG == e_brainpool_p256_r1) {
       v_signature := valueof(
                              m_signature_ecdsaBrainpoolP256r1(
                                                               m_ecdsaP256Signature(
                                                                                    m_eccP256CurvePoint_x_only(
                                                                                                               substr(v_tbs_signed, 0, 32)
                                                                                                               ),
                                                                                    substr(v_tbs_signed, 32, 32)
                                                                                    )
                                                               )
                              );
      } else if (PX_VE_ALG == e_brainpool_p384_r1) {
       v_signature := valueof(
                              m_signature_ecdsaBrainpoolP384r1(
                                                               m_ecdsaP384Signature(
                                                                                    m_eccP384CurvePoint_x_only(
                                                                                                               substr(v_tbs_signed, 0, 48)
                                                                                                               ),
                                                                                    substr(v_tbs_signed, 48, 48)
                                                                                    )
                                                               )
                              );
      }
      log("f_build_pki_secured_request_message_signed_with_pop: v_signature= ", v_signature);
Yann Garcia's avatar
Yann Garcia committed
      v_ieee1609dot2_signed_data := m_etsiTs103097Data_signed(
                                                              m_signedData(
                                                                           sha256,
                                                                           v_tbs,
Yann Garcia's avatar
Yann Garcia committed
                                                                           )
      // Encode EtsiTs103097Data-Signed data structure
      v_encoded_request := bit2oct(encvalue(v_ieee1609dot2_signed_data));
      // Encrypt encode EtsiTs103097Data-Signed data structure
      if (PICS_SEC_FIXED_KEYS) {
        p_salt := '77C0637C3558B3238FDE1EEC376DA080BE4076FB8491CA0F8C19FD34DF298CEB'O;
      }
Yann Garcia's avatar
Yann Garcia committed

      if (PX_EC_ALG == e_nist_p256) {
        v_encrypted_request := f_encryptWithEciesNistp256WithSha256(v_encoded_request, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, PICS_SEC_FIXED_KEYS);
      } else if (PX_EC_ALG == e_brainpool_p256_r1) {
        v_encrypted_request := f_encryptWithEciesBrainpoolp256WithSha256(v_encoded_request, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, PICS_SEC_FIXED_KEYS);
      } else {
        log("f_build_pki_secured_request_message_signed_with_pop: Wrong encryption variant");
        return false;
      }
      log("f_build_pki_secured_request_message_signed_with_pop: p_aes_sym_key= ", p_aes_sym_key);
      log("f_build_pki_secured_request_message_signed_with_pop: p_encrypted_sym_key= ", p_encrypted_sym_key);
      log("f_build_pki_secured_request_message_signed_with_pop: p_authentication_vector= ", p_authentication_vector);
      log("f_build_pki_secured_request_message_signed_with_pop: p_nonce= ", p_nonce);
      log("f_build_pki_secured_request_message_signed_with_pop: p_recipientId= ", p_recipientId);
      if (p_recipientId == int2oct(0, 8)) {
        log("f_build_pki_secured_request_message_signed_with_pop: f_hashWithSha256(v_encrypted_sym_key)= ", f_hashWithSha256(p_encrypted_sym_key));
        v_recipientId := f_HashedId8FromSha256(f_hashWithSha256(p_encrypted_sym_key));
      } else {
        v_recipientId := p_recipientId;
      }
      log("f_build_pki_secured_request_message_signed_with_pop: v_recipientId= ", v_recipientId);
      // Fill Certificate template with the public compressed keys (canonical form)
      if (v_public_compressed_ephemeral_mode == 0) {
        v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key));
      } else {
        v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key));
      }
      if (PX_EC_ALG == e_nist_p256) {
        v_encrypted_data_encryption_key := valueof(
                                                   m_encryptedDataEncryptionKey_eciesNistP256(
                                                                                              m_evciesP256EncryptedKey(
                                                                                                                       v_eccP256_curve_point,
                                                                                                                       p_encrypted_sym_key, 
                                                                                                                       p_authentication_vector
                                                                                                                       )));
      } else if (PX_EC_ALG == e_brainpool_p256_r1) {
        v_encrypted_data_encryption_key := valueof(
                                                   m_encryptedDataEncryptionKey_eciesBrainpoolP256r1(
                                                                                                     m_evciesP256EncryptedKey(
                                                                                                                              v_eccP256_curve_point,
                                                                                                                              p_encrypted_sym_key, 
                                                                                                                              p_authentication_vector
                                                                                                                              )));
      } else {
        log("f_build_pki_secured_request_message_signed_with_pop: Wrong encryption variant");
        return false;
      }
      
      p_ieee1609dot2_signed_and_encrypted_data := valueof(
                                                          m_etsiTs103097Data_encrypted(
                                                                                       m_encryptedData(
                                                                                                       {
Yann Garcia's avatar
Yann Garcia committed
                                                                                                         m_recipientInfo_certRecipInfo(
                                                                                                                                       m_pKRecipientInfo(
                                                                                                                                                         v_recipientId,
                                                                                                                                                         v_encrypted_data_encryption_key
                                                                                                                                                         ))
                                                                                                         },
                                                                                                       m_SymmetricCiphertext_aes128ccm(
                                                                                                                                       m_aesCcmCiphertext(
                                                                                                                                                          p_nonce,
                                                                                                                                                          v_encrypted_request
                                                                                                                                                          )
                                                                                                                                       )
Yann Garcia's avatar
Yann Garcia committed
      // The 'p_request_hash' shall be the SHA256 digest of the OER representation of the topmost EtsiTs103097Data-Encoded structure
      v_enc_value := encvalue(p_ieee1609dot2_signed_and_encrypted_data);
      if (PICS_SEC_FIXED_KEYS) {
        p_request_hash := '10ED97A2F2933DD3AC55F47022D125E18F5E1AA024613E616A75BA4979EFE318'O;
      } else {
        p_request_hash := f_hashWithSha256(bit2oct(v_enc_value));
      }
      log("f_build_pki_secured_request_message_signed_with_pop: p_request_hash= ", p_request_hash);
      
      log("<<< f_build_pki_secured_request_message_signed_with_pop: ", p_pki_message);
      return true;
    } // End of function f_build_pki_secured_request_message_signed_with_pop
    
    /**
     * @desc Build a signed and encrypted PKI request message without POP with signature
     * @param p_recipientId         Recipient identifier to be inclued in encrypted layer.
     *                              If value is int2oct(0. 8), the recipient id is the HashedId8 of the symmetric key used by the sender to encrypt the message to which the response is built
     * @param p_public_key_compressed The public compressed key (canonical form) for encryption
     * @param p_compressed_mode      The compressed mode of the public compressed key (canonical form) for encryption
     * @param p_pki_message         The PKI message to be secured
     * @param p_ieee1609dot2_signed_and_encrypted_data The secured message
     * @return true on success, false otherwise
     */
    function f_build_pki_secured_request_message(
                                                 in HashedId8 p_recipientId,
                                                 in octetstring p_public_key_compressed,
                                                 in integer p_compressed_mode,
                                                 in octetstring p_salt,
                                                 in octetstring p_pki_message,
                                                 out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data,
                                                 out Oct16 p_aes_sym_key,
                                                 out Oct16 p_encrypted_sym_key,
                                                 out Oct16 p_authentication_vector,
                                                 out Oct12 p_nonce,
                                                 out Oct32 p_request_hash
                                                 ) return boolean {
      // Local variables
      var template (value) EccP256CurvePoint v_eccP256_curve_point;
      var HashedId8 v_recipientId;
      var octetstring v_public_compressed_ephemeral_key;
      var integer v_public_compressed_ephemeral_mode;
      var octetstring v_encrypted_request;
      var EncryptedDataEncryptionKey v_encrypted_data_encryption_key;
Yann Garcia's avatar
Yann Garcia committed
      var bitstring v_enc_value;
      
      log(">>> f_build_pki_secured_request_message");
      
      // Encrypt encode EtsiTs103097Data-Signed data structure
      if (PICS_SEC_FIXED_KEYS) {
        p_salt := '77C0637C3558B3238FDE1EEC376DA080BE4076FB8491CA0F8C19FD34DF298CEB'O;
Yann Garcia's avatar
Yann Garcia committed
      if (PX_EC_ALG == e_nist_p256) {
        v_encrypted_request := f_encryptWithEciesNistp256WithSha256(p_pki_message, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, PICS_SEC_FIXED_KEYS);
      } else if (PX_EC_ALG == e_brainpool_p256_r1) {
        v_encrypted_request := f_encryptWithEciesBrainpoolp256WithSha256(p_pki_message, p_public_key_compressed, p_compressed_mode, p_salt, v_public_compressed_ephemeral_key, v_public_compressed_ephemeral_mode, p_aes_sym_key, p_encrypted_sym_key, p_authentication_vector, p_nonce, PICS_SEC_FIXED_KEYS);
      } else {
        log("f_build_pki_secured_request_message: Wrong encryption variant");
        return false;
      }
      log("f_build_pki_secured_request_message: p_aes_sym_key= ", p_aes_sym_key);
      log("f_build_pki_secured_request_message: p_encrypted_sym_key= ", p_encrypted_sym_key);
      log("f_build_pki_secured_request_message: p_authentication_vector= ", p_authentication_vector);
      log("f_build_pki_secured_request_message: p_nonce= ", p_nonce);
      log("f_build_pki_secured_request_message: p_recipientId= ", p_recipientId);
      if (p_recipientId == int2oct(0, 8)) {
        log("f_build_pki_secured_request_message: f_hashWithSha256(v_encrypted_sym_key)= ", f_hashWithSha256(p_encrypted_sym_key));
        v_recipientId := f_HashedId8FromSha256(f_hashWithSha256(p_encrypted_sym_key));
      } else {
        v_recipientId := p_recipientId;
      }
      log("f_build_pki_secured_request_message: v_recipientId= ", v_recipientId);
Yann Garcia's avatar
Yann Garcia committed
      // Fill Certificate template with the public compressed keys (canonical form)
      if (v_public_compressed_ephemeral_mode == 0) {
        v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_compressed_ephemeral_key));
Yann Garcia's avatar
Yann Garcia committed
      } else {
        v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_compressed_ephemeral_key));
Yann Garcia's avatar
Yann Garcia committed
      }
      if (PX_EC_ALG == e_nist_p256) {
        v_encrypted_data_encryption_key := valueof(
                                                   m_encryptedDataEncryptionKey_eciesNistP256(
                                                                                              m_evciesP256EncryptedKey(
                                                                                                                       v_eccP256_curve_point,
                                                                                                                       p_encrypted_sym_key, 
                                                                                                                       p_authentication_vector
                                                                                                                       )));
      } else if (PX_EC_ALG == e_brainpool_p256_r1) {
        v_encrypted_data_encryption_key := valueof(
                                                   m_encryptedDataEncryptionKey_eciesBrainpoolP256r1(
                                                                                                     m_evciesP256EncryptedKey(
                                                                                                                              v_eccP256_curve_point,
                                                                                                                              p_encrypted_sym_key, 
                                                                                                                              p_authentication_vector
                                                                                                                              )));
      }
Yann Garcia's avatar
Yann Garcia committed
      p_ieee1609dot2_signed_and_encrypted_data := valueof(
                                                          m_etsiTs103097Data_encrypted(
                                                                                       m_encryptedData(
                                                                                                       {
                                                                                                        m_recipientInfo_signedDataRecipInfo(
                                                                                                                                            m_pKRecipientInfo(
                                                                                                                                                              v_recipientId,
                                                                                                                                                              v_encrypted_data_encryption_key
                                                                                                                                                              ))
                                                                                                        },
Yann Garcia's avatar
Yann Garcia committed
                                                                                                       m_SymmetricCiphertext_aes128ccm(
                                                                                                                                       m_aesCcmCiphertext(
Yann Garcia's avatar
Yann Garcia committed
      // The 'p_request_hash' shall be the SHA256 digest of the OER representation of the topmost EtsiTs103097Data-Encoded structure
      v_enc_value := encvalue(p_ieee1609dot2_signed_and_encrypted_data);
      if (PICS_SEC_FIXED_KEYS) {
        p_request_hash := '10ED97A2F2933DD3AC55F47022D125E18F5E1AA024613E616A75BA4979EFE318'O;
      } else {
        p_request_hash := f_hashWithSha256(bit2oct(v_enc_value));
      }
      log("f_build_pki_secured_request_message: p_request_hash= ", p_request_hash);
      
      log("<<< f_build_pki_secured_request_message: ", p_ieee1609dot2_signed_and_encrypted_data);
Yann Garcia's avatar
Yann Garcia committed
      return true;
    } // End of function f_build_pki_secured_request_message
    
    /**
     * @desc Build a signed and encrypted PKI response message
     * @param p_private_key         Private key for signature
     * @param p_signer_identifier   Signer identifier for signature, could be self or certificate HashedId8
     * @param p_recipientId         Recipient identifier to be inclued in encrypted layer.
     *                              If value is int2oct(0. 8), the recipient id is the HashedId8 of the symmetric key used by the sender to encrypt the message to which the response is built
     * @param p_public_key_compressed The public compressed key (canonical form) for encryption
     * @param p_compressed_mode      The compressed mode of the public compressed key (canonical form) for encryption
     * @param p_pki_message         The PKI message to be secured
     * @param p_ieee1609dot2_signed_and_encrypted_data The secured message
     * @return true on success, false otherwise
     */
    function f_build_pki_secured_response_message(
                                                 in octetstring p_private_key,
                                                 in SignerIdentifier p_signer_identifier,
                                                 in octetstring p_pki_message,
                                                 in Oct16 p_aes_sym_key,
                                                 in Oct12 p_nonce,
                                                 out Ieee1609Dot2Data p_ieee1609dot2_signed_and_encrypted_data
                                                 ) return boolean {
      // Local variables
      var template (value) ToBeSignedData v_tbs;
      var octetstring v_tbs_signed;
      var template (value) Ieee1609Dot2Data v_ieee1609dot2_signed_data;
      var octetstring v_encoded_inner_ec_response;
      var HashedId8 v_recipientId;
      var octetstring v_encrypted_inner_ec_response;
      
      // Signed the encoded PKI message
      v_tbs := m_toBeSignedData(
                                m_signedDataPayload(
                                                    m_etsiTs103097Data_unsecured(p_pki_message)
                                                   ),
                                m_headerInfo_inner_ec_response(c_its_aid_SCR, f_getCurrentTimeUtc())
                               );
      if (ischosen(p_signer_identifier.self_)) {
        v_tbs_signed := f_signWithEcdsaNistp256WithSha256(bit2oct(encvalue(v_tbs)), int2oct(0, 32), p_private_key);
      } else {
        var charstring v_certificate_id;
        var octetstring v_hash;
        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_signWithEcdsaNistp256WithSha256(bit2oct(encvalue(v_tbs)), v_hash, p_private_key);
      }
      // Add the signature and create EtsiTs103097Data-Signed data structure
      v_ieee1609dot2_signed_data := m_etsiTs103097Data_signed(
                                                              m_signedData(
                                                                           sha256,
                                                                           v_tbs,
                                                                           p_signer_identifier,
                                                                           m_signature_ecdsaNistP256(
                                                                                                     m_ecdsaP256Signature(
                                                                                                                          m_eccP256CurvePoint_x_only(
                                                                                                                                                     substr(v_tbs_signed, 0, 32)
                                                                                                                                                     ),
                                                                                                                          substr(v_tbs_signed, 32, 32)
                                                                                                                          )
                                                                                                     )
                                                                           )
                                                      );
      // Encode EtsiTs103097Data-Signed data structure
      v_encoded_inner_ec_response := bit2oct(encvalue(v_ieee1609dot2_signed_data));
      v_encrypted_inner_ec_response := fx_encrypt_aes_128_ccm_test(p_aes_sym_key, p_nonce, v_encoded_inner_ec_response);
      v_recipientId := f_HashedId8FromSha256(f_hashWithSha256(p_aes_sym_key));
      log("v_recipientId= ", v_recipientId);
      // Fill Certificate template with the public compressed keys (canonical form)
      p_ieee1609dot2_signed_and_encrypted_data := valueof(
                                                          m_etsiTs103097Data_encrypted(
                                                                                       m_encryptedData(
                                                                                                       {
                                                                                                        m_recipientInfo_pskRecipInfo(
                                                                                                                                     v_recipientId
                                                                                                                                     )
                                                                                                       },
                                                                                                       m_SymmetricCiphertext_aes128ccm(
                                                                                                                                       m_aesCcmCiphertext(
                                                                                                                                                          p_nonce,
                                                                                                                                                          v_encrypted_inner_ec_response
                                                                                                                                                         )
                                                                                                                                      )
                                                                                                      )
                                                                                       )
                                                         );
      
      log("<<< f_build_pki_secured_response_message: ", p_ieee1609dot2_signed_and_encrypted_data);
      return true;
    } // End of function f_build_pki_secured_response_message
     * @desc Verify the protocol element of the Pki message. 
     *       If p_check_security is set to false, only decryption and decoding of the outer message are verified.
     * @param p_private_key         Private key for decryption
     * @param p_publicEphemeralCompressedKey
     * @param p_publicEphemeralCompressedKeyMode
     * @param p_issuer              Issuer
     * @param p_certificate         Certificate to use for verification key
     * @param p_ieee1609dot2_encrypted_and_signed_data The received encrypted and signed data
     * @param p_check_security      Set to true to verify PKI protocol element such as signatures...
     * @param p_etsi_ts_102941_data The EtsiTs102941Data message
     * @return true on success, false otherwise
     */
                                  in octetstring p_private_enc_key,
                                  in Oct16 p_aes_sym_key,
                                  in Oct16 p_authentication_vector, // TODO Tobe removed
                                  in Certificate p_certificate, // TODO Tobe removed
                                  in Ieee1609Dot2Data p_ieee1609dot2_encrypted_and_signed_data,
                                  in boolean p_check_security := true,
                                  out EtsiTs102941Data p_etsi_ts_102941_data
                                  ) return boolean {
garciay's avatar
garciay committed
      // Local variables
      var octetstring v_public_enc_key;
      var integer v_compressed_enc_key_mode;
      var octetstring v_plain_message;
      var Ieee1609Dot2Data v_ieee1609dot2_signed_data;
      var Certificate v_certificate;
      var bitstring v_etsi_ts_102941_data_msg;
      var bitstring v_tbs;
      var boolean v_ret;
      
      log(">>> f_verify_pki_message: p_private_enc_key= ", p_private_enc_key);
      log(">>> f_verify_pki_message: p_aes_sym_key= ", p_aes_sym_key);
      log(">>> f_verify_pki_message: p_authentication_vector= ", p_authentication_vector);
      log(">>> f_verify_pki_message: p_issuer= ", p_issuer);
      
      // TODO Check p_ieee1609dot2_encrypted_and_signed_data.content.encryptedData.recipients[0].pskRecipInfo. See IEEE Std 1609.2-2017 Clause 6.3.34 PreSharedKeyRecipientInfo
      
Yann Garcia's avatar
Yann Garcia committed
      v_plain_message := fx_decrypt_aes_128_ccm_test(p_aes_sym_key, p_ieee1609dot2_encrypted_and_signed_data.content.encryptedData.ciphertext.aes128ccm.nonce, p_ieee1609dot2_encrypted_and_signed_data.content.encryptedData.ciphertext.aes128ccm.ccmCiphertext);
      if (isbound(v_plain_message) == false) {
        return false;
      }
Yann Garcia's avatar
Yann Garcia committed
      log("f_verify_pki_message: v_plain_message= ", v_plain_message);

      // 2. Decode it
      v_tbs := oct2bit(v_plain_message);
      if (decvalue(v_tbs, v_ieee1609dot2_signed_data) != 0) {
Yann Garcia's avatar
Yann Garcia committed
      log("f_verify_pki_message: v_ieee1609dot2_signed_data= ", v_ieee1609dot2_signed_data);
      // 3. Check the signature
Yann Garcia's avatar
Yann Garcia committed
      log("f_verify_pki_message: v_ieee1609dot2_signed_data.content.signedData.tbsData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData);
      v_tbs := encvalue(v_ieee1609dot2_signed_data.content.signedData.tbsData);
      if (f_getCertificateFromDigest(v_ieee1609dot2_signed_data.content.signedData.signer.digest, v_certificate) == false) {
        if (p_check_security == true) {
          return false;
        }
      }
Yann Garcia's avatar
Yann Garcia committed
      //log("f_verify_pki_message: v_certificate= ", v_certificate);
      v_ret := false;
      if (ischosen(v_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256)) {
        if (ischosen(v_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0)) {
          v_ret := f_verifyWithEcdsaNistp256WithSha256(
                                                       bit2oct(v_tbs),
                                                       p_issuer,
                                                       v_ieee1609dot2_signed_data.content.signedData.signature_.ecdsaNistP256Signature.rSig.x_only & v_ieee1609dot2_signed_data.content.signedData.signature_.ecdsaNistP256Signature.sSig,
                                                       v_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_0,
                                                       0);
        } else {
          v_ret := f_verifyWithEcdsaNistp256WithSha256(
                                                       bit2oct(v_tbs),
                                                       p_issuer,
                                                       v_ieee1609dot2_signed_data.content.signedData.signature_.ecdsaNistP256Signature.rSig.x_only & v_ieee1609dot2_signed_data.content.signedData.signature_.ecdsaNistP256Signature.sSig,
                                                       v_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_1,
                                                       1);
        }
      } else if (ischosen(v_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1)) {
        if (ischosen(v_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0)) {
          v_ret := f_verifyWithEcdsaBrainpoolp256WithSha256(
                                                       bit2oct(v_tbs),
                                                       p_issuer,
                                                       v_ieee1609dot2_signed_data.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.rSig.x_only & v_ieee1609dot2_signed_data.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.sSig,
                                                       v_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_0,
                                                       0);
        } else {
          v_ret := f_verifyWithEcdsaBrainpoolp256WithSha256(
                                                       bit2oct(v_tbs),
                                                       p_issuer,
                                                       v_ieee1609dot2_signed_data.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.rSig.x_only & v_ieee1609dot2_signed_data.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.sSig,
                                                       v_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1.compressed_y_1,
                                                       1);
        }
      } else if (ischosen(v_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1)) {
        if (ischosen(v_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1.compressed_y_0)) {
          v_ret := f_verifyWithEcdsaBrainpoolp384WithSha384(
                                                       bit2oct(v_tbs),
                                                       p_issuer,
                                                       v_ieee1609dot2_signed_data.content.signedData.signature_.ecdsaBrainpoolP384r1Signature.rSig.x_only & v_ieee1609dot2_signed_data.content.signedData.signature_.ecdsaBrainpoolP384r1Signature.sSig,
                                                       v_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1.compressed_y_0,
                                                       0);
        } else {
          v_ret := f_verifyWithEcdsaBrainpoolp384WithSha384(
                                                       bit2oct(v_tbs),
                                                       p_issuer,
                                                       v_ieee1609dot2_signed_data.content.signedData.signature_.ecdsaBrainpoolP384r1Signature.rSig.x_only & v_ieee1609dot2_signed_data.content.signedData.signature_.ecdsaBrainpoolP384r1Signature.sSig,
                                                       v_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1.compressed_y_1,
                                                       1);
        }
garciay's avatar
garciay committed
      if (v_ret == false) {
        if (p_check_security == true) {
          return false;
        }
      // 4. Return the PKI message
      log("v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData= ", v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData);
      v_etsi_ts_102941_data_msg := oct2bit(v_ieee1609dot2_signed_data.content.signedData.tbsData.payload.data.content.unsecuredData);
      if (decvalue(v_etsi_ts_102941_data_msg, p_etsi_ts_102941_data) != 0) {
        return false;
      }

garciay's avatar
garciay committed
      if (p_etsi_ts_102941_data.version != PkiProtocolVersion) {
        if (p_check_security == true) {
          return false;
        }
garciay's avatar
garciay committed
      
      return true;
    } // End of function f_verify_pki_message
Yann Garcia's avatar
Yann Garcia committed
     * @desc Verify the EC certificate generated by the EA entity
     * @param p_ec_certificate        The new EC certificate
Yann Garcia's avatar
Yann Garcia committed
     * @param p_ea_certificate        The certificate issuer
     * @param p_public_key_compressed The public compressed key (canonical form) generated for the InnerEcRequest
Yann Garcia's avatar
Yann Garcia committed
     * @param p_compressed_mode       The public compressed key mode
     * @return true on success, false otherwise
     */
Yann Garcia's avatar
Yann Garcia committed
    function f_verify_ec_certificate(
                                     in Certificate p_ec_certificate,
Yann Garcia's avatar
Yann Garcia committed
                                     in Certificate p_ea_certificate,
                                     in octetstring p_public_key_compressed,
                                     in integer p_compressed_mode
Yann Garcia's avatar
Yann Garcia committed
      var bitstring v_encoded_cert;
      var HashedId8 v_ec_cert_hashed_id8;
      
      // Calculate the HashedId8 of the whole certificate
      v_encoded_cert := encvalue(p_ec_certificate);
      v_ec_cert_hashed_id8 := f_HashedId8FromSha256(f_hashWithSha256(bit2oct(v_encoded_cert)));
      log("f_verify_ec_certificate: EC certificate HashedId8: ", v_ec_cert_hashed_id8);
Yann Garcia's avatar
Yann Garcia committed
      log("f_verify_ec_certificate: ", match(p_ec_certificate.issuer, mw_issuerIdentifier_self()));
      if (match(p_ec_certificate.issuer, mw_issuerIdentifier_self)) {
        return false;
      }
Yann Garcia's avatar
Yann Garcia committed
      // Check EC certificate signature
      // TODO Who sign the EC certificate?
Yann Garcia's avatar
Yann Garcia committed
      if (f_verifyCertificateSignatureWithPublicKey(p_ec_certificate, p_ea_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) {
Yann Garcia's avatar
Yann Garcia committed
        log("f_verify_ec_certificate: Signature not verified");
        return false;
Yann Garcia's avatar
Yann Garcia committed
      return true;
    } // End of function f_verify_ec_certificate
Yann Garcia's avatar
Yann Garcia committed
     * @desc Verify the generated AT certificate 
     * @param p_at_certificate        The new AT certificate
     * @param p_ea_certificate        The certificate issuer
     * @param p_public_key_compressed The public compressed key (canonical form) generated for the InnerAtRequest
     * @param p_compressed_mode       The public compressed key mode
     * @return true on success, false otherwise
     */
Yann Garcia's avatar
Yann Garcia committed
    function f_verify_at_certificate(
                                     in Certificate p_at_certificate,
                                     in Certificate p_aa_certificate,
                                     in octetstring p_public_key_compressed,
                                     in integer p_compressed_mode
Yann Garcia's avatar
Yann Garcia committed
      var bitstring v_encoded_cert;
      var HashedId8 v_at_cert_hashed_id8;
      
      // Calculate the HashedId8 of the whole certificate
      v_encoded_cert := encvalue(p_at_certificate);
      v_at_cert_hashed_id8 := f_HashedId8FromSha256(f_hashWithSha256(bit2oct(v_encoded_cert)));
      log("f_verify_at_certificate: EC certificate HashedId8: ", v_at_cert_hashed_id8);
Yann Garcia's avatar
Yann Garcia committed
      log("f_verify_at_certificate: ", match(p_at_certificate.issuer, mw_issuerIdentifier_self()));
      if (match(p_at_certificate.issuer, mw_issuerIdentifier_self)) {
        return false;
      }
Yann Garcia's avatar
Yann Garcia committed
      // Check EC certificate signature
      // TODO Who sign the EC certificate?
      if (f_verifyCertificateSignatureWithPublicKey(p_at_certificate, p_aa_certificate.toBeSigned.verifyKeyIndicator.verificationKey) == false) {
        log("f_verify_at_certificate: Signature not verified");
        return false;
      }
Yann Garcia's avatar
Yann Garcia committed
      return true;
    } // End of function f_verify_at_certificate
Yann Garcia's avatar
Yann Garcia committed
  } // End of group inner_ec_xxx
garciay's avatar
garciay committed

  group security_function { // TODO To be moved in LibItsSecurity_Function module

    function f_extract_enc_key(
                               in Certificate p_certificate,
                               out octetstring p_public_enc_key,
                               out integer p_compressed_enc_key_mode
                               ) return boolean {
      log(">>> f_extract_enc_key: ", p_certificate);
      
garciay's avatar
garciay committed
      if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256)) {
        if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0)) {
          p_public_enc_key := p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_0;
          p_compressed_enc_key_mode := 0;
garciay's avatar
garciay committed
        } else if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1)) {
          p_public_enc_key := p_certificate.toBeSigned.encryptionKey.publicKey.eciesNistP256.compressed_y_1;
          p_compressed_enc_key_mode := 1;
garciay's avatar
garciay committed
        } else {
          log("f_extract_enc_key: Non canonical certificate: ", p_certificate);
garciay's avatar
garciay committed
          return false;
        }
      } else if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1)) {
        if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0)) {
          p_public_enc_key := p_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_0;
          p_compressed_enc_key_mode := 0;
garciay's avatar
garciay committed
        } else if (ischosen(p_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1)) {
          p_public_enc_key := p_certificate.toBeSigned.encryptionKey.publicKey.eciesBrainpoolP256r1.compressed_y_1;
          p_compressed_enc_key_mode := 0;
        } else {
          log("f_extract_enc_key: Non canonical certificate: ", p_certificate);
garciay's avatar
garciay committed
          return false;
        }
      } else {
        log("f_extract_enc_key: Invalid certificate: ", p_certificate);
garciay's avatar
garciay committed
        return false;
      }

      return true;
    } // End of function f_extract_enc_key
    
  } // End of group security_function
Yann Garcia's avatar
Yann Garcia committed
  group altsteps {