LibItsPki_Functions.ttcn 185 KB
Newer Older
                                                                             p_inner_ec_request.requestedSubjectAttributes.validityPeriod,
                                                                             p_inner_ec_request.requestedSubjectAttributes.region,
                                                                             p_inner_ec_request.requestedSubjectAttributes.assuranceLevel,
                                                                             p_inner_ec_request.publicKeys.encryptionKey
                                                                             )
                                                  )
                        );
Yann Garcia's avatar
Yann Garcia committed
      // Encode it ==> Get octetstring
      v_tbs := encvalue(v_cert.toBeSigned);
      // Sign the certificate
      v_sig := f_signWithEcdsa(bit2oct(v_tbs), p_digest, p_private_key);
      if (PX_VE_ALG == e_nist_p256) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaNistP256(
                                                               m_ecdsaP256Signature(
                                                                                    m_eccP256CurvePoint_x_only(
                                                                                                               substr(v_sig, 0, 32)
                                                                                                               ),
                                                                                    substr(v_sig, 32, 32)
                                                                                    )
                                                               )
                                     );
      } else if (PX_VE_ALG == e_brainpool_p256_r1) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaBrainpoolP256r1(
                                                                      m_ecdsaP256Signature(
                                                                                           m_eccP256CurvePoint_x_only(
                                                                                                                      substr(v_sig, 0, 32)
                                                                                                                      ),
                                                                                           substr(v_sig, 32, 32)
                                                                                           )
                                                                      )
                                     );
Yann Garcia's avatar
Yann Garcia committed
      } else if (PX_VE_ALG == e_brainpool_p384_r1) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaBrainpoolP384r1(
                                                                      m_ecdsaP384Signature(
                                                                                           m_eccP384CurvePoint_x_only(
                                                                                                                      substr(v_sig, 0, 48)
                                                                                                                      ),
                                                                                           substr(v_sig, 48, 48)
                                                                                           )
                                                                      )
                                     );
      p_ec_certificate := valueof(v_cert);
      log("f_generate_ec_certificate_for_inner_ec_response: p_ec_certificate= ", p_ec_certificate);
Yann Garcia's avatar
Yann Garcia committed
      
      return true;
    } // End of function f_generate_ec_certificate_for_inner_ec_response
    
    function f_generate_at_certificate(
                                       in octetstring p_private_key,
                                       in InnerEcRequest p_inner_ec_request,
                                       out Certificate p_at_certificate
                                       ) return boolean {
      var SequenceOfPsidSsp v_appPermissions := { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs
        valueof(m_appPermissions(36, { bitmapSsp := '830001'O })), 
        valueof(m_appPermissions(37, { bitmapSsp := '830001'O })) 
      };
      var template (value) EtsiTs103097Certificate v_cert;
      var bitstring v_tbs;
      var Oct32 v_sig;
      var bitstring v_enc_msg;
      var PublicVerificationKey v_public_verification_key;
      if (PX_EC_ALG == e_nist_p256) {
        v_public_verification_key := valueof(
                                             m_publicVerificationKey_ecdsaNistP256(
                                                                                   p_inner_ec_request.publicKeys.verificationKey.ecdsaNistP256
                                                                                   ));
      } else if (PX_EC_ALG == e_brainpool_p256_r1) {
        v_public_verification_key := valueof(
                                             m_publicVerificationKey_ecdsaBrainpoolP256r1(
                                                                                          p_inner_ec_request.publicKeys.verificationKey.ecdsaBrainpoolP256r1
                                                                                          ));
      } else {
        // Error
        log("f_generate_ec_certificate: Wrong encryption algorithm, check PX_EC_ALG");
        return false;
      }
      v_cert := m_etsiTs103097Certificate(
                                          m_issuerIdentifier_sha256AndDigest(f_HashedId8FromSha256(f_hashWithSha256('616263'O))),
                                          m_toBeSignedCertificate_at(
                                                                     v_appPermissions,
                                                                     m_verificationKeyIndicator_verificationKey(
                                                                                                                v_public_verification_key
                                                                                                                ),
                                                                     m_validityPeriod(
Yann Garcia's avatar
Yann Garcia committed
                                                                                      f_getCurrentTime() / 1000,
                                                                                      m_duration_years(1)
                                                                                      ),
                                                                     m_geographicRegion_identifiedRegion(
                                                                                                         {
                                                                                                           m_identifiedRegion_country_only(12), 
                                                                                                           m_identifiedRegion_country_only(34)
                                                                                                           }
                                                                                                         )
                                                                     )
                                          );
      // Encode it ==> Get octetstring
      v_tbs := encvalue(v_cert.toBeSigned);
      
      // Sign the certificate
      v_sig := f_signWithEcdsa(bit2oct(v_tbs), int2oct(11, 32), p_private_key);
      if ((PX_VE_ALG == e_nist_p256) or (PX_VE_ALG == e_brainpool_p256_r1)) {
        v_cert.signature_ := m_signature_ecdsaNistP256(
                                                       m_ecdsaP256Signature(
                                                                            m_eccP256CurvePoint_x_only(
                                                                                                       substr(v_sig, 0, 32)
                                                                                                       ),
                                                                            substr(v_sig, 32, 32)
                                                                            )
                                                       );
      } else if (PX_VE_ALG == e_brainpool_p384_r1) {
        v_cert.signature_ := m_signature_ecdsaBrainpoolP384r1(
                                                              m_ecdsaP384Signature(
                                                                                   m_eccP384CurvePoint_x_only(
                                                                                                              substr(v_sig, 0, 48)
                                                                                                              ),
                                                                                   substr(v_sig, 48, 48)
                                                                                   )
                                                              );
      }
      log("v_cert= ", v_cert);
      
      p_at_certificate := valueof(v_cert);
      return true;
    } // End of function f_generate_at_certificate
    
    function f_generate_at_certificate_for_authorization_response(
                                                                  in InnerAtRequest p_inner_at_request,
                                                                  in octetstring p_private_key,
                                                                  in octetstring p_digest,
                                                                  out EtsiTs103097Certificate p_at_certificate
                                                                  ) return boolean {
      var EtsiTs103097Certificate v_cert;
      var IssuerIdentifier v_issuer;
      var bitstring v_tbs;
      var octetstring v_sig;
      
      log(">>> f_generate_at_certificate_for_authorization_response");

      /*v_issuer := valueof(m_issuerIdentifier_sha256AndDigest(f_HashedId8FromSha256(p_digest))); // TODO Check sha256/384 f_HashedId8FromSha384
      v_cert := valueof(
                        m_etsiTs103097Certificate(
                                                  v_issuer,
                                                  m_toBeSignedCertificate_ec(
                                                                             p_inner_at_request.requestedSubjectAttributes.id,
                                                                             p_inner_at_request.requestedSubjectAttributes.appPermissions,
                                                                             m_verificationKeyIndicator_verificationKey(
                                                                                                                        p_inner_at_request.publicKeys.verificationKey
                                                                                                                        ),
                                                                             p_inner_at_request.requestedSubjectAttributes.validityPeriod,
                                                                             p_inner_at_request.requestedSubjectAttributes.region,
                                                                             p_inner_at_request.requestedSubjectAttributes.assuranceLevel,
                                                                             p_inner_at_request.publicKeys.encryptionKey
                                                                             )
                                                  )
                        );
      // Encode it ==> Get octetstring
      v_tbs := encvalue(v_cert.toBeSigned);
      // Sign the certificate
      v_sig := f_signWithEcdsa(bit2oct(v_tbs), p_digest, p_private_key);
      if (PX_VE_ALG == e_nist_p256) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaNistP256(
                                                               m_ecdsaP256Signature(
                                                                                    m_eccP256CurvePoint_x_only(
                                                                                                               substr(v_sig, 0, 32)
                                                                                                               ),
                                                                                    substr(v_sig, 32, 32)
                                                                                    )
                                                               )
                                     );
      } else if (PX_VE_ALG == e_brainpool_p256_r1) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaBrainpoolP256r1(
                                                                      m_ecdsaP256Signature(
                                                                                           m_eccP256CurvePoint_x_only(
                                                                                                                      substr(v_sig, 0, 32)
                                                                                                                      ),
                                                                                           substr(v_sig, 32, 32)
                                                                                           )
                                                                      )
                                     );
      } else if (PX_VE_ALG == e_brainpool_p384_r1) {
        v_cert.signature_ := valueof(
                                     m_signature_ecdsaBrainpoolP384r1(
                                                                      m_ecdsaP384Signature(
                                                                                           m_eccP384CurvePoint_x_only(
                                                                                                                      substr(v_sig, 0, 48)
                                                                                                                      ),
                                                                                           substr(v_sig, 48, 48)
                                                                                           )
                                                                      )
                                     );
      }
      p_at_certificate := valueof(v_cert);*/
      log("f_generate_at_certificate_for_authorization_response: p_at_certificate= ", p_at_certificate);
      
      return true;
    } // End of function f_generate_at_certificate_for_authorization_response
    
  } // End of group generate_certificates 
Yann Garcia's avatar
Yann Garcia committed
  
  group inner_ec_xxx {
    
garciay's avatar
garciay committed
    function f_generate_inner_ec_request(
                                         out octetstring p_public_key_compressed,
                                         out integer p_compressed_mode,
garciay's avatar
garciay committed
                                         out InnerEcRequest p_inner_ec_request
                                         ) return boolean {
Yann Garcia's avatar
Yann Garcia committed
      // Local variables
Yann Garcia's avatar
Yann Garcia committed
      var Oct32 v_publicKeyX;
      var Oct32 v_publicKeyY;
      var EccP256CurvePoint v_eccP256_curve_point;

      log (">>> f_generate_inner_ec_request");
Yann Garcia's avatar
Yann Garcia committed
      // Generate keys for the certificate to be requested
      if (f_generate_key_pair(p_private_key, v_publicKeyX, v_publicKeyY, p_public_key_compressed, p_compressed_mode) == false) {
        log ("f_generate_inner_ec_request: failed to generate keys");
Yann Garcia's avatar
Yann Garcia committed
        return false;
      }
      if (p_compressed_mode == 0) {
        v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(p_public_key_compressed));
Yann Garcia's avatar
Yann Garcia committed
      } else {
        v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(p_public_key_compressed));
Yann Garcia's avatar
Yann Garcia committed
      }
garciay's avatar
garciay committed
      // Build the Proof of Possession InnerEcRequest
Yann Garcia's avatar
Yann Garcia committed
      p_inner_ec_request := valueof(
                                    m_innerEcRequest(
                                                     PICS_ITS_S_CANONICAL_ID,
Yann Garcia's avatar
Yann Garcia committed
                                                     m_publicKeys(
                                                                  m_publicVerificationKey_ecdsaNistP256(v_eccP256_curve_point)
Yann Garcia's avatar
Yann Garcia committed
                                                                  ),
                                                     m_certificateSubjectAttributes(
                                                                                    { // ETSI TS 102 965 Table A.1: ETSI ITS standardized ITS-AIDs
                                                                                      valueof(m_appPermissions(c_its_aid_SCR, { bitmapSsp := '00C0'O }))
Yann Garcia's avatar
Yann Garcia committed
                                                                                    },
                                                                                    m_validityPeriod(
Yann Garcia's avatar
Yann Garcia committed
                                                                                                     f_getCurrentTime() / 1000,
                                                                                                     m_duration_years(1) // TODO Use PIXIT
Yann Garcia's avatar
Yann Garcia committed
                                                                                    m_geographicRegion_identifiedRegion(
                                                                                                                        {
                                                                                                                          m_identifiedRegion_country_only(12), // TODO Use PIXIT
                                                                                                                          m_identifiedRegion_country_only(34) // TODO Use PIXIT
                                                                                                                          }
                                                                                                                        ),
garciay's avatar
garciay committed
                                                                                    'C0'O // TODO Use PIXIT
      if (PICS_SECPKI_REENROLMENT) { // This is a re-enrolment, the identifier of its current valid Enrolment Credential
        log("f_generate_inner_ec_request: This is a re-enrolment");
        p_inner_ec_request.itsId := PX_EC_HASHED_ID8;
      }
      log("f_generate_inner_ec_request: ", p_inner_ec_request);
Yann Garcia's avatar
Yann Garcia committed
      
      return true;
garciay's avatar
garciay committed
    } // End of function f_generate_inner_ec_request
garciay's avatar
garciay committed
    function f_generate_inner_ec_request_signed_for_pop(
garciay's avatar
garciay committed
                                                        in InnerEcRequest p_inner_ec_request,
                                                        out Ieee1609Dot2Data p_inner_ec_request_signed_for_pop
Yann Garcia's avatar
Yann Garcia committed
    ) return boolean {
      // Local variables
      var template (value) EccP256CurvePoint v_eccP256_curve_point;
      var octetstring v_encoded_inner_ec_request;
      var template (value) ToBeSignedData v_tbs;
      var Signature v_signature;
garciay's avatar
garciay committed
      
      // Encode it
      v_encoded_inner_ec_request := bit2oct(encvalue(p_inner_ec_request));
      // Signed the encoded InnerEcRequestSignedForPop
      v_tbs := m_toBeSignedData(
                                m_signedDataPayload(
                                                    m_etsiTs103097Data_unsecured(
                                                                                 v_encoded_inner_ec_request
                                                                                 )
                                                   ),
                                m_headerInfo_inner_pki_request(
                                                               -,
                                                               (f_getCurrentTime() * 1000) //us
garciay's avatar
garciay committed
                               );
      // Signed the encoded InnerEcRequestSignedForPop
      v_tbs_signed := f_signWithEcdsa(bit2oct(encvalue(v_tbs)), int2oct(0, 32), p_private_key);
garciay's avatar
garciay committed
      // Finalyse signed InnerEcRequestSignedForPop
      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_generate_inner_ec_request_signed_for_pop: v_signature= ", v_signature);
garciay's avatar
garciay committed
      p_inner_ec_request_signed_for_pop := valueof(
                                                   m_etsiTs103097Data_signed(
                                                                             m_signedData(
                                                                                          sha256,
                                                                                          v_tbs,
                                                                                          m_signerIdentifier_self,
      
      log("<<< f_generate_inner_ec_request_signed_for_pop: p_inner_ec_request_signed_for_pop= ", p_inner_ec_request_signed_for_pop);
garciay's avatar
garciay committed
      return true;
    } // End of function f_generate_inner_ec_request_signed_for_pop
Yann Garcia's avatar
Yann Garcia committed

    function f_verify_inner_ec_request_signed_for_pop(
                                                      in EtsiTs102941Data p_etsi_ts_102941_data,
                                                      out InnerEcRequest p_inner_ec_request
                                                      ) return boolean {
      var bitstring v_msg_bit;

      log(">>> f_verify_inner_ec_request_signed_for_pop: ", p_etsi_ts_102941_data);
      
      // 1. Decode content
      v_msg_bit := oct2bit(p_etsi_ts_102941_data.content.enrolmentRequest.content.signedData.tbsData.payload.data.content.unsecuredData);
      if (decvalue(v_msg_bit, p_inner_ec_request) != 0) {
        log("f_verify_inner_ec_request_signed_for_pop: Failed to decode InnerEcRequest");
        return false;
      } else {
        log("f_verify_inner_ec_request_signed_for_pop: v_inner_ec_request= ", p_inner_ec_request);

        // 2. Verify the InnerEcRequestSignedForPop signature
        // TODO
Yann Garcia's avatar
Yann Garcia committed
      }
      
      return true;
    } // End of function f_verify_inner_ec_request_signed_for_pop
    function f_generate_inner_ec_response(
                                          in octetstring p_inner_ec_request_hash,
                                          in EtsiTs103097Certificate p_certificate,
                                          out InnerEcResponse p_inner_ec_response
                                         ) return boolean {
      // Local variables
      
      // Build the Proof of Possession InnerEcResponse
      p_inner_ec_response := valueof(
                                     m_innerEcResponse_ok(
                                                          substr(p_inner_ec_request_hash, 0, 16),
                                                          p_certificate
                                                          )
                                     );
      
      return true;
    } // End of function f_generate_inner_ec_response
    
garciay's avatar
garciay committed
  } // End of group inner_ec_xxx

  group inner_at_xxx {

    function f_generate_inner_at_request(
                                         in Certificate p_ea_certificate,
                                         in Oct8 p_ea_hashed_id8,
                                         in Certificate p_ec_certificate,
                                         in octetstring p_ec_private_key,
Yann Garcia's avatar
Yann Garcia committed
                                         out octetstring p_private_key,
                                         out octetstring p_public_key_compressed,
                                         out integer p_compressed_key_mode,
                                         out octetstring p_private_enc_key,
                                         out octetstring p_public_compressed_enc_key,
                                         out integer p_compressed_enc_key_mode,
                                         out InnerAtRequest p_inner_at_request
                                         ) return boolean {
      // Local variables
Yann Garcia's avatar
Yann Garcia committed
      var octetstring v_public_key_x;
      var octetstring v_public_key_y;
      var octetstring v_public_enc_key_x;
      var octetstring v_public_enc_key_y;
      var bitstring v_enc_value;
      var octetstring v_ec_hash;
      var Oct8 v_ec_hashed_id8;
Yann Garcia's avatar
Yann Garcia committed
      var octetstring public_enc_key_x;
      var octetstring public_enc_key_y;
      var Oct32 v_hmac_key;
      var octetstring v_message_to_tag;
      var Oct16 v_key_tag;
      var octetstring v_hash_shared_at_request;
      var template (value) ToBeSignedData v_tbs;
      var octetstring v_tbs_signed;
      var Ieee1609Dot2Data v_signed_at_signature;
      var template (value) EccP256CurvePoint v_eccP256_curve_point;
      var template (value) EccP256CurvePoint v_enc_eccP256_curve_point;
      var HashAlgorithm v_hashId;
      var Signature v_signature;
Yann Garcia's avatar
Yann Garcia committed
      // Generate verification keys for the certificate to be requested
      if (f_generate_key_pair(p_private_key, v_public_key_x, v_public_key_y, p_public_key_compressed, p_compressed_key_mode) == false) {
        log("f_generate_inner_at_request: Failed to generate verification key");
        return false;
      }
      log ("f_generate_inner_at_request: AT verification private key: ", p_private_key);
      log ("f_generate_inner_at_request: AT verification public compressed key: ", p_public_key_compressed);
      log ("f_generate_inner_at_request: AT verification public compressed mode: ", p_compressed_key_mode);
      // Generate encryption keys for the certificate to be requested
      if (PX_INCLUDE_ENCRYPTION_KEYS) {
        if (f_generate_key_pair(p_private_enc_key, v_public_enc_key_x, v_public_enc_key_y, p_public_compressed_enc_key, p_compressed_enc_key_mode) == false) {
          log("f_generate_inner_at_request: Failed to generate encryption key");
          return false;
        }
      } else {
        p_private_enc_key := ''O;
        p_public_compressed_enc_key := ''O;
        p_compressed_enc_key_mode := -1;
      }
      
      // Calculate the whole certificate SHA
      v_enc_value := encvalue(p_ec_certificate);
      if (ischosen(p_ec_certificate.issuer.sha256AndDigest)) {
        v_ec_hash := f_hashWithSha256(bit2oct(v_enc_value));
        v_ec_hashed_id8 := f_HashedId8FromSha256(v_ec_hash);
        v_ec_hash := f_hashWithSha384(bit2oct(v_enc_value));
        v_ec_hashed_id8 := f_HashedId8FromSha384(v_ec_hash);
      log("f_generate_inner_at_request: v_ec_hash= ", v_ec_hash);
      
      // Generate 32 octets length secret key
garciay's avatar
garciay committed
      v_hmac_key := f_hashWithSha256(int2oct(f_getCurrentTime(), 12));
      log("f_generate_inner_at_request: v_hmac_key= ", v_hmac_key);
      // Generate tag based on the concatenation of verification keys & encryption keys
Yann Garcia's avatar
Yann Garcia committed
      v_message_to_tag := v_public_key_x & v_public_key_y & v_public_enc_key_x & v_public_enc_key_y;
      log("f_generate_inner_at_request: v_message_to_tag= ", v_message_to_tag); // FIXME encryption keys could be optional
Yann Garcia's avatar
Yann Garcia committed
      v_key_tag := fx_hmac_sha256(v_hmac_key, v_message_to_tag); // TODO Rename and use a wrapper function
      log("f_generate_inner_at_request: v_key_tag= ", v_key_tag);

      // Build the SharedAtRequest
      p_inner_at_request.sharedAtRequest := valueof(
                                                    m_shared_at_request(
                                                                        p_ea_hashed_id8, // eaId identifies the EA certificate shared with EA entity
                                                                        substr(v_key_tag, 0, 16), // Calculated keyTag
                                                                        valueof(
                                                                                m_certificate_subject_attributes( // FIXME Review subjectPermissions
                                                                                                                 p_ec_certificate.toBeSigned.appPermissions,
                                                                                                                 p_ec_certificate.toBeSigned.certRequestPermissions,
                                                                                                                 p_ec_certificate.toBeSigned.id,
                                                                                                                 p_ec_certificate.toBeSigned.validityPeriod,
                                                                                                                 p_ec_certificate.toBeSigned.region,
                                                                                                                 p_ec_certificate.toBeSigned.assuranceLevel
                                                                                                                  ))) // Desired attributes
                                                    );
      // Calculate the hash of the SharedAtRequest
      v_hash_shared_at_request := f_hashWithSha256(bit2oct(encvalue(p_inner_at_request.sharedAtRequest)));
      log("f_generate_inner_at_request: v_hash_shared_at_request= ", v_hash_shared_at_request);
      
      // Build the ETsiTs103097Data-SignedExternalPayload
      v_tbs := m_toBeSignedData(
                                m_signedDataPayload_ext(v_hash_shared_at_request), // Payload containing extDataHash
                                m_headerInfo_inner_pki_request( // HeaderInfo
                                                               -,
                                                               (f_getCurrentTime()) * 1000) //us
      log("f_generate_inner_at_request: v_tbs= ", v_tbs);
      // Signed ToBeSigned payload using the private key of EC certificate obtained from Enrolment request
      // In case of ITS-S privacy, v_signed_at_signature contained the data to be encrypted
      if (ischosen(p_ec_certificate.signature_.ecdsaBrainpoolP384r1Signature)) {
        v_hashId := sha384;
        v_tbs_signed := f_signWithEcdsaBrainpoolp384WithSha384(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
        v_signature := valueof(
                               m_signature_ecdsaBrainpoolP384r1(
                                                                m_ecdsaP384Signature(
                                                                                     m_eccP384CurvePoint_x_only(
                                                                                                                substr(v_tbs_signed, 0, 48)
                                                                                                                ),
                                                                                     substr(v_tbs_signed, 48, 48)
                                                                                     )
                                                                )
                                                        );
      } else {
        v_hashId := sha256;
        if (ischosen(p_ec_certificate.signature_.ecdsaBrainpoolP256r1Signature)) {
          v_tbs_signed := f_signWithEcdsaBrainpoolp256WithSha256(bit2oct(encvalue(v_tbs)), v_ec_hash, p_ec_private_key);
          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 (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_at_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_at_signature= ", v_signed_at_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_at_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);
Yann Garcia's avatar
Yann Garcia committed
          } else if (PX_EC_ALG == e_brainpool_p256_r1) {
            v_enc_signed_ec_signature := f_encryptWithEciesBrainpoolp256WithSha256(bit2oct(encvalue(v_signed_at_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);
Yann Garcia's avatar
Yann Garcia committed
          } else {
            log("f_generate_inner_at_request: Wrong encryption variant");
            return false;
          }
          if (v_compressed_mode == 0) {
            v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_public_enc_key));
          } else {
            v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_public_enc_key));
          }
          log("f_generate_inner_at_request: v_eccP256_curve_point= ", v_eccP256_curve_point);
          log("f_generate_inner_at_request: v_encrypted_sym_key= ", v_encrypted_sym_key);
          log("f_generate_inner_at_request: v_authentication_vector= ", v_authentication_vector);
          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_at_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);
Yann Garcia's avatar
Yann Garcia committed
          } else if (PX_EC_ALG == e_brainpool_p256_r1) {
            v_enc_signed_ec_signature := f_encryptWithEciesBrainpoolp256WithSha256(bit2oct(encvalue(v_signed_at_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);
Yann Garcia's avatar
Yann Garcia committed
          } 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_at_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_verify_inner_at_request_signed_for_pop(
                                                      in EtsiTs102941Data p_etsi_ts_102941_data,
                                                      out InnerAtRequest p_inner_at_request
                                                      ) return boolean {
      var bitstring v_msg_bit;

      log(">>> f_verify_inner_at_request_signed_for_pop: ", p_etsi_ts_102941_data);
      
      // 1. Decode content
      v_msg_bit := oct2bit(p_etsi_ts_102941_data.content.enrolmentRequest.content.signedData.tbsData.payload.data.content.unsecuredData);
      if (decvalue(v_msg_bit, p_inner_at_request) != 0) {
        log("f_verify_inner_at_request_signed_for_pop: Failed to decode InnerEcRequest");
        return false;
      } else {
        log("f_verify_inner_at_request_signed_for_pop: v_inner_at_request= ", p_inner_at_request);

        // 2. Verify the InnerEcRequestSignedForPop signature
        // TODO
      }
      
      return true;
    } // End of function f_verify_inner_at_request_signed_for_pop
    
    function f_generate_inner_at_response(
                                          in octetstring p_authorization_request_hash,
                                          in EtsiTs103097Certificate p_certificate,
                                          out InnerAtResponse p_authorization_response
                                          ) return boolean {
      // Local variables
      // Build the Proof of Possession InnerEcResponse
      p_authorization_response := valueof(
                                          m_innerAtResponse_ok(
                                                               substr(p_authorization_request_hash, 0, 16),
                                                               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 {
    
    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 {
        // TODO Create a a_await_at_http_request_from_iut(
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;
Yann Garcia's avatar
Yann Garcia committed
          if (f_verify_pki_response_message(p_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, 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_response_message(p_private_key, v_aes_sym_key, v_authentication_vector, vc_eaWholeHash, v_response.response.body.binary_body.ieee1609dot2_data, false, v_etsi_ts_102941_data) == false) {
Yann Garcia's avatar
Yann Garcia committed
            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
    
    function f_await_ec_request_send_response(
                                              out InnerEcResponse p_inner_ec_response
                                              ) runs on ItsPkiHttp return boolean {
      var HttpMessage v_request;
      var boolean v_result := false;
      
      log(">>> f_await_ec_request_send_response");
      
      tc_ac.start;
      alt {
        [] a_await_at_http_response_from_iut(
                                             mw_http_request(
                                                             mw_http_request_post(
                                                                                  PICS_HTTP_POST_URI_EC,
                                                                                  -,
                                                                                  mw_http_message_body_binary(
                                                                                                              mw_binary_body_ieee1609dot2_data(
                                                                                                                                               mw_enrolmentRequestMessage(
                                                                                                                                                                          mw_encryptedData(
                                                                                                                                                                                           -,
                                                                                                                                                                                           mw_SymmetricCiphertext_aes128ccm
                                                                                                                                                                                           )))))),
                                             v_request
                                             ) {
          var Ieee1609Dot2Data v_ieee1609dot2_signed_and_encrypted_data;
          var EtsiTs102941Data v_etsi_ts_102941_data;
          var Oct16 v_request_hash;
          var Oct16 v_aes_enc_key;
          var InnerEcRequest v_inner_ec_request;
          var template (value) HttpMessage v_response;
          var HeaderLines v_headers;
          
          tc_ac.stop;
          
          f_init_default_headers_list(-, "inner_ec_response", v_headers);
          
          if (f_verify_pki_request_message(vc_eaPrivateEncKey, vc_eaWholeHash/*salt*/, vc_eaWholeHash, v_request.request.body.binary_body.ieee1609dot2_data, false, v_request_hash, v_etsi_ts_102941_data, v_aes_enc_key) == false) { // Cannot decrypt the message
            log("f_await_ec_request_send_response: Failed to verify PKI message ***");
            // Send error message
            v_response := m_http_response(m_http_response_ko(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), v_headers, 400, "Bad request")); // Initialize v_reponse with an error message
          } else {
            log("f_await_ec_request_send_response: Receive ", v_etsi_ts_102941_data, " ***");
            if (f_verify_inner_ec_request_signed_for_pop(v_etsi_ts_102941_data, v_inner_ec_request) == false) {
              log("f_await_ec_request_send_response: Failed to verify PKI message ***");
              // Send error message
              f_http_build_inner_ec_response(v_inner_ec_request/*Not required*/, cantparse, v_request_hash, -, -, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
              v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), v_headers));
            } else {
              f_http_build_inner_ec_response(v_inner_ec_request, ok, v_request_hash, vc_eaPrivateKey, vc_eaWholeHash, v_aes_enc_key, p_inner_ec_response, v_ieee1609dot2_signed_and_encrypted_data);
            v_response := m_http_response(m_http_response_ok(m_http_message_body_binary(m_binary_body_ieee1609dot2_data(v_ieee1609dot2_signed_and_encrypted_data)), v_headers));
            v_result := true;
            }
            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.timeout {
          log("f_await_ec_request_send_response: Expected message not received ***");
        }
      } // End of 'alt' statement
      
      return v_result;
    } // End of function f_await_ec_request_send_response
    
  } // 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_pki_request(-, (f_getCurrentTime() * 1000)/*us*/)
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 (PICS_SECPKI_REENROLMENT == false) { // This is the first enrolment, we used Factory keys
        //if (ischosen(p_signer_identifier.self_)) {
        v_tbs_signed := f_signWithEcdsa(bit2oct(encvalue(v_tbs)), int2oct(0, 32), p_private_key);
        /*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)), PX_EC_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)
                                                                                                               ),