LibItsPki_Functions.ttcn 76.7 KB
Newer Older
      // Encode EtsiTs103097Data-Signed data structure
Yann Garcia's avatar
Yann Garcia committed
      v_encoded_inner_ec_request := bit2oct(encvalue(v_ieee1609dot2_signed_data));
      // Encrypt encode EtsiTs103097Data-Signed data structure
Yann Garcia's avatar
Yann Garcia committed
      v_encrypted_inner_ec_request := f_encryptWithEciesNistp256WithSha256(v_encoded_inner_ec_request, p_publicKeyCompressed, p_compressedMode, v_publicEphemeralKeyCompressed, v_ephemeralKeyModeCompressed, v_encrypted_sym_key, v_authentication_vector, v_nonce);
      log("p_recipientId=", p_recipientId);
      if (p_recipientId == int2oct(0, 8)) {
        log("v_encrypted_sym_key=", v_encrypted_sym_key);
        log("f_hashWithSha256(v_encrypted_sym_key=", f_hashWithSha256(v_encrypted_sym_key));
        v_recipientId := f_HashedId8FromSha256(f_hashWithSha256(v_encrypted_sym_key));
      } else {
        v_recipientId := p_recipientId;
      }
      log("v_recipientId=", v_recipientId);
Yann Garcia's avatar
Yann Garcia committed
      // Fill Certificate template with the public compressed keys (canonical form)
      if (v_ephemeralKeyModeCompressed == 0) {
        v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_0(v_publicEphemeralKeyCompressed));
      } else {
        v_eccP256_curve_point := valueof(m_eccP256CurvePoint_compressed_y_1(v_publicEphemeralKeyCompressed));
      }
      p_ieee1609dot2_signed_and_encrypted_data := valueof(
                                                          m_etsiTs103097Data_encrypted(
                                                                                       m_encryptedData(
                                                                                                       {
                                                                                                        m_recipientInfo_signedDataRecipInfo(
                                                                                                                                            m_pKRecipientInfo(
                                                                                                                                                              v_recipientId,
                                                                                                                                                              m_encryptedDataEncryptionKey_eciesNistP256(
                                                                                                                                                                                                      m_evciesP256EncryptedKey(
                                                                                                                                                                                                                               v_eccP256_curve_point,
                                                                                                                                                                                                                               v_encrypted_sym_key, 
                                                                                                                                                                                                                               v_authentication_vector
                                                                                                        ))))
                                                                                                       },
                                                                                                       m_SymmetricCiphertext_aes128ccm(
                                                                                                                                       m_aesCcmCiphertext(
                                                                                                                                                          v_nonce, 
                                                                                                                                                          v_encrypted_inner_ec_request
                                                                                                                                                         )
                                                                                                                                      )
                                                                                                      )
                                                                                       )
                                                         );
      
      return true;
garciay's avatar
garciay committed
    } // End of function f_build_pki_secured_message
    
    /**
     * @desc Verify the protocol element of the Pki message 
     * @param p_private_key         Private key for encryption
     * @param p_issuer              Issuer
     * @param p_peer_certificate    IUT EA certificate identifier
     * @param p_ieee1609dot2_encrypted_and_signed_data The public compressed key (canonical form) for encryption
     * @param p_check_security      Set to true to check signatures
     * @param p_etsi_ts_102941_data The EtsiTs102941Data message
     * @return true on success, false otherwise
     */
    function f_verify_pki_message(
                                  in octetstring v_private_enc_key,
                                  in octetstring p_issuer,
                                  in Certificate p_peer_certificate,
                                  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 Ieee1609Dot2Data v_ieee1609dot2_signed_data;
      var bitstring v_etsi_ts_102941_data_msg;
      var bitstring v_tbs;
      var boolean v_ret;
garciay's avatar
garciay committed
      if (f_decrypt(v_private_enc_key, p_ieee1609dot2_encrypted_and_signed_data, v_ieee1609dot2_signed_data) == false) {
        if (p_check_security == true) {
          return false;
        }
      }
      log("v_ieee1609dot2_signed_data= ", v_ieee1609dot2_signed_data);
      
      // 2. Check the signature
      v_tbs := encvalue(v_ieee1609dot2_signed_data.content.signedData.tbsData);
      if (ischosen(p_peer_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,
                                                     p_peer_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,
                                                     p_peer_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256.compressed_y_1,
                                                     1);
      }
garciay's avatar
garciay committed
      if (v_ret == false) {
        if (p_check_security == true) {
          return false;
        }
      }

      // 3. Retrun the PKI message
      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
    
    /**
     * @desc Verify the generated EA certificate 
     * @param p_ea_certificate      The new EA certificate
     * @param p_publicKeyCompressed The public compressed key (canonical form) for signature check
     * @param p_compressedMode      The public compressed key mode
     * @return true on success, false otherwise
     */
    function f_verify_ea_certificate(
                                     in Certificate p_ea_certificate,
                                     in octetstring p_publicKeyCompressed,
                                     in integer p_compressedMode
                                     ) return boolean {
      var bitstring v_encoded_tbs;
      var boolean v_result;
      
      // Check certificate format
      v_result := match(p_ea_certificate, mw_etsiTs103097Certificate(mw_issuerIdentifier_self, mw_toBeSignedCertificate_ea, -));
      // Check the signer
      
      // Check EA certificate signature
      v_encoded_tbs := encvalue(p_ea_certificate.toBeSigned);
      v_result := v_result and f_verifyWithEcdsaNistp256WithSha256(
                                                                   bit2oct(v_encoded_tbs),
                                                                   int2oct(0, 32), // self
                                                                   p_ea_certificate.signature_.ecdsaNistP256Signature.rSig.x_only & p_ea_certificate.signature_.ecdsaNistP256Signature.sSig,
                                                                   p_publicKeyCompressed, 
                                                                   p_compressedMode);
      
      return v_result;
    } // End of function f_verify_ea_certificate
    
    /**
     * @desc Verify the generated AA certificate 
     * @param p_aa_certificate      The new EA certificate
     * @param p_publicKeyCompressed The public compressed key (canonical form) for signature check
     * @param p_compressedMode      The public compressed key mode
     * @return true on success, false otherwise
     */
    function f_verify_aa_certificate(
                                     in Certificate p_aa_certificate,
                                     in octetstring p_publicKeyCompressed,
                                     in integer p_compressedMode
                                     ) return boolean {
      var bitstring v_encoded_tbs;
      var boolean v_result;
      
      // Check certificate format
      v_result := match(p_aa_certificate, mw_etsiTs103097Certificate(mw_issuerIdentifier_self, mw_toBeSignedCertificate_aa, -));
      // Check the signer
      
      // Check EA certificate signature
      v_encoded_tbs := encvalue(p_aa_certificate.toBeSigned);
      v_result := v_result and f_verifyWithEcdsaNistp256WithSha256(
                                                                   bit2oct(v_encoded_tbs),
                                                                   int2oct(0, 32), // self
                                                                   p_aa_certificate.signature_.ecdsaNistP256Signature.rSig.x_only & p_aa_certificate.signature_.ecdsaNistP256Signature.sSig,
                                                                   p_publicKeyCompressed, 
                                                                   p_compressedMode);
      
      return v_result;
    } // End of function f_verify_aa_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 {
      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;
        } 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;
        } else {
          log("f_extract_enc_key: Non canonical EA certificate");
          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;
        } 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 EA certificate");
          return false;
        }
      } else {
        log("f_extract_enc_key: Invalid EA certificate");
        return false;
      }

      return true;
    } // End of function f_extract_enc_key
    
  } // End of group security_function
  group altstes {
    
    altstep a_default_pki() runs on ItsPki {
      [] pkiPort.receive {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected PKI message received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
    }
    
    altstep a_default_pki_http() runs on ItsPkiHttp {
      [] httpPort.receive( 
                          mw_http_response(
                                           mw_http_response_ko
                                           )) {
        tc_ac.stop;
        log("*** a_default: ERROR: HTTP Server error ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [] httpPort.receive(mw_http_request) {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP Request received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [] httpPort.receive(mw_http_response) {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP Response received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
      [] httpPort.receive {
        tc_ac.stop;
        log("*** a_default: ERROR: Unexpected HTTP message received ***");
        f_selfOrClientSyncAndVerdict("error", e_error);
      }
    }
  }
  
Yann Garcia's avatar
Yann Garcia committed
} // End of module LibItsPki_Functions