Rev

Rev 3274 | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | Download | SVN | Bug Tracker

module ItsGenCert_Functions {
   
  // LibIts
  import from IEEE1609dot2BaseTypes language "ASN.1:1997" all;
  import from IEEE1609dot2 language "ASN.1:1997" all;
  import from EtsiTs103097Module language "ASN.1:1997" all;
   
  // LibItsSecurity
  import from LibItsSecurity_EncdecDeclarations all;
  import from LibItsSecurity_TypesAndValues all;
  import from LibItsSecurity_Templates all;
  import from LibItsSecurity_Functions all;
  import from LibItsSecurity_Pixits all;
   
  // AtsGenCert
  import from ItsGenCert_TypeAndValues all;
  import from ItsGenCert_Templates all;
  import from ItsGenCert_Pics all;
   
  function f_generate_signing_keys(
                                   in certificate_params p_certificate_params,
                                   inout certificate_details p_certificate_details
                                   ) return integer {
    if (p_certificate_params.curve == e_nist_p256) {
      f_generate_key_pair_nistp256(p_certificate_details.private_key, p_certificate_details.public_key_x, p_certificate_details.public_key_y, p_certificate_details.public_key_compressed, p_certificate_details.public_key_compressed_mode);
    } else if (p_certificate_params.curve == e_brainpool_p256) {
      f_generate_key_pair_brainpoolp256(p_certificate_details.private_key, p_certificate_details.public_key_x, p_certificate_details.public_key_y, p_certificate_details.public_key_compressed, p_certificate_details.public_key_compressed_mode);
    } else if (p_certificate_params.curve == e_brainpool_p384) {
      f_generate_key_pair_brainpoolp384(p_certificate_details.private_key, p_certificate_details.public_key_x, p_certificate_details.public_key_y, p_certificate_details.public_key_compressed, p_certificate_details.public_key_compressed_mode);
    } else {
      log("f_generate_signing_keys: Unsupported curve");
      return -1;
    }
   
    if (p_certificate_params.encryption_key == true) {
      if (p_certificate_params.encryption_curve == e_nist_p256) {
        f_generate_key_pair_nistp256(p_certificate_details.private_enc_key, p_certificate_details.public_enc_key_x, p_certificate_details.public_enc_key_y, p_certificate_details.public_enc_key_compressed, p_certificate_details.public_enc_key_compressed_mode);
      } else if (p_certificate_params.encryption_curve == e_brainpool_p256) {
        f_generate_key_pair_brainpoolp256(p_certificate_details.private_enc_key, p_certificate_details.public_enc_key_x, p_certificate_details.public_enc_key_y, p_certificate_details.public_enc_key_compressed, p_certificate_details.public_enc_key_compressed_mode);
      } else {
        log("f_generate_signing_keys: Unsupported encryption curve");
        return -1;
      }
    }
   
    return 0;
  } // End of function f_generate_signing_keys
   
  function f_fill_certificate(
                              in certificate_params p_certificate_params,
                              inout certificate_details p_certificate_details
                              ) return integer {
  var VerificationKeyIndicator v_publicVerificationKey;
  if (p_certificate_params.curve == e_nist_p256) {
    if (p_certificate_details.public_key_compressed_mode == 0) {
      v_publicVerificationKey := valueof(
                                         m_verificationKeyIndicator_verificationKey(
                                                                                    m_publicVerificationKey_ecdsaNistP256(
                                                                                                                          m_eccP256CurvePoint_compressed_y_0(
                                                                                                                                                             p_certificate_details.public_key_compressed
                                        ))));
    } else {
      v_publicVerificationKey := valueof(
                                         m_verificationKeyIndicator_verificationKey(
                                                                                    m_publicVerificationKey_ecdsaNistP256(
                                                                                                                          m_eccP256CurvePoint_compressed_y_1(
                                                                                                                                                             p_certificate_details.public_key_compressed
                                        ))));
    }
  } else if (p_certificate_params.curve == e_brainpool_p256) {
    if (p_certificate_details.public_key_compressed_mode == 0) {
      v_publicVerificationKey := valueof(
                                         m_verificationKeyIndicator_verificationKey(
                                                                                    m_publicVerificationKey_ecdsaBrainpoolP256r1(
                                                                                                                                 m_eccP256CurvePoint_compressed_y_0(
                                                                                                                                                                    p_certificate_details.public_key_compressed
                                        ))));
    } else {
      v_publicVerificationKey := valueof(
                                         m_verificationKeyIndicator_verificationKey(
                                                                                    m_publicVerificationKey_ecdsaBrainpoolP256r1(
                                                                                                                                 m_eccP256CurvePoint_compressed_y_1(
                                                                                                                                                                    p_certificate_details.public_key_compressed
                                        ))));
    }
  } else {
    if (p_certificate_details.public_key_compressed_mode == 0) {
      v_publicVerificationKey := valueof(
                                         m_verificationKeyIndicator_verificationKey(
                                                                                    m_publicVerificationKey_ecdsaBrainpoolP384r1(
                                                                                                                                 m_eccP384CurvePoint_compressed_y_0(
                                                                                                                                                                    p_certificate_details.public_key_compressed
                                        ))));
    } else {
      v_publicVerificationKey := valueof(
                                         m_verificationKeyIndicator_verificationKey(
                                                                                    m_publicVerificationKey_ecdsaBrainpoolP384r1(
                                                                                                                                 m_eccP384CurvePoint_compressed_y_1(
                                                                                                                                                                    p_certificate_details.public_key_compressed
                                        ))));
    }
  }
  p_certificate_details.certificate := valueof(
                                               m_etsiTs103097Certificate(
                                                                         m_issuerIdentifier_self(p_certificate_params.hash_algorithm),
                                                                         m_toBeSignedCertificate(
                                                                                                 { name := p_certificate_params.certificate_id },
                                                                                                 v_publicVerificationKey,
                                                                                                 p_certificate_params.validity_period,
                                                                                                 p_certificate_params.region,
                                                                                                 p_certificate_params.app_permissions,
                                                                                                 p_certificate_params.issuing_permissions
                                                                               )
                                                                )
                                               );
    if (p_certificate_params.encryption_key == true) {
      if (p_certificate_params.encryption_curve == e_nist_p256) {
        if (p_certificate_details.public_enc_key_compressed_mode == 0) {
          p_certificate_details.certificate.toBeSigned.encryptionKey := valueof(m_encryptionKey(
                                                                                                aes128Ccm,
                                                                                                m_publicEncryptionKey_ecdsaNistP256(
                                                                                                                                    m_eccP256CurvePoint_compressed_y_0(
                                                                                                                                                                       p_certificate_details.public_enc_key_compressed
                                                                                                                                                                       )))
                                                                               );
        } else {
          p_certificate_details.certificate.toBeSigned.encryptionKey := valueof(m_encryptionKey(
                                                                                                aes128Ccm,
                                                                                                m_publicEncryptionKey_ecdsaNistP256(
                                                                                                                                    m_eccP256CurvePoint_compressed_y_1(
                                                                                                                                                                       p_certificate_details.public_enc_key_compressed
                                                                                                                                                                       )))
                                                                             );
        }
      } else if (p_certificate_params.encryption_curve == e_brainpool_p256) {
        if (p_certificate_details.public_enc_key_compressed_mode == 0) {
          p_certificate_details.certificate.toBeSigned.encryptionKey := valueof(m_encryptionKey(
                                                                                                aes128Ccm,
                                                                                                m_publicEncryptionKey_eciesBrainpoolP256r1(
                                                                                                                                           m_eccP256CurvePoint_compressed_y_0(
                                                                                                                                                                              p_certificate_details.public_enc_key_compressed
                                                                                                                                                                              )))
                                                                               );
        } else {
          p_certificate_details.certificate.toBeSigned.encryptionKey := valueof(m_encryptionKey(
                                                                                                aes128Ccm,
                                                                                                m_publicEncryptionKey_eciesBrainpoolP256r1(
                                                                                                                                           m_eccP256CurvePoint_compressed_y_1(
                                                                                                                                                                              p_certificate_details.public_enc_key_compressed
                                                                                                                                                                              )))
                                                                               );
        }
      }
    }
   
    return 0;
  } // End of function f_fill_certificate
   
  function f_generate_certificate(
                                  in certificate_params p_certificate_params,
                                  in certificate_details p_issuer_certificate_details,
                                  inout certificate_details p_certificate_details
                                  ) return integer {
    var bitstring v_enc_msg;
    var octetstring v_issuer;
    var octetstring v_signature;

    // Encode it ==> Get octetstring
    v_enc_msg := encvalue(p_certificate_details.certificate.toBeSigned);
   
    // Sign the certificate using ECDSA/SHA-256 (NIST p-256)
    if (p_certificate_params.curve == e_nist_p256) {
      if (p_issuer_certificate_details.certificate_id != p_certificate_details.certificate_id) { // This is not a CA certificate
        v_issuer := p_issuer_certificate_details.hash;
      } else {
        v_issuer := int2oct(0, 32); // Hash of empty string
      }
      v_signature := f_signWithEcdsaNistp256WithSha256(bit2oct(v_enc_msg), v_issuer, p_issuer_certificate_details.private_key);
      if (lengthof(v_signature) != 64) {
        setverdict(fail, "Wrong signature size, shall be 64 instead of ", lengthof(v_signature));
        stop;
      }
      p_certificate_details.certificate.signature_ := valueof(
                                                              m_signature_ecdsaNistP256(
                                                                                        m_ecdsaP256Signature(
                                                                                                             m_eccP256CurvePoint_x_only(
                                                                                                                                        substr(v_signature, 0, 32)
                                                                                                                                        ),
                                                                                                             substr(v_signature, 32, 32)
                                                                                                             )
                                                                                        ));
    } else if (p_certificate_params.curve == e_brainpool_p256) {
      if (p_issuer_certificate_details.issuer != p_issuer_certificate_details.hashid8) { // This is not a CA certificate
        v_issuer := p_issuer_certificate_details.hash;
      } else {
        v_issuer := int2oct(0, 32); // Hash of empty string
      }
      v_signature := f_signWithEcdsaBrainpoolp256WithSha256(bit2oct(v_enc_msg), v_issuer, p_issuer_certificate_details.private_key);
      if (lengthof(v_signature) != 64) {
        setverdict(fail, "Wrong signature size, shall be 64 instead of ", lengthof(v_signature));
        stop;
      }
      p_certificate_details.certificate.signature_ := valueof(
                                                              m_signature_ecdsaBrainpoolP256r1(
                                                                                               m_ecdsaP256Signature(
                                                                                                                    m_eccP256CurvePoint_x_only(
                                                                                                                                               substr(v_signature, 0, 32)
                                                                                                                                               ),
                                                                                                                    substr(v_signature, 32, 32)
                                                                                                                    )
                                                                                               ));
    } else if (p_certificate_params.curve == e_brainpool_p384) {
      if (p_issuer_certificate_details.issuer != p_issuer_certificate_details.hashid8) { // This is not a CA certificate
        v_issuer := p_issuer_certificate_details.hash;
      } else {
        v_issuer := int2oct(0, 48);
      }
      v_signature := f_signWithEcdsaBrainpoolp384WithSha384(bit2oct(v_enc_msg), v_issuer, p_issuer_certificate_details.private_key);
      if (lengthof(v_signature) != 96) {
        setverdict(fail, "Wrong signature size, shall be 96 instead of ", lengthof(v_signature));
        stop;
      }
      p_certificate_details.certificate.signature_ := valueof(m_signature_ecdsaBrainpoolP384r1(
                                                                                               m_ecdsaP384Signature(
                                                                                                                    m_eccP384CurvePoint_x_only(
                                                                                                                                               substr(v_signature, 0, 48)
                                                                                                                                               ),
                                                                                                                    substr(v_signature, 48, 48)
                                                                                                                    )
                                                                                               ));
    } else {
      log("f_generate_certificate: Unsupported curve");
      return -1;
    }
       
    return 0;
  } // End of function f_generate_certificate
   
  function f_finalyse_certificate(
                                  in certificate_params p_certificate_params,
                                  in certificate_details_list p_certificate_details_list,
                                  inout certificate_details p_certificate_details
                                  ) return integer {
    // Set the issuer
    if (p_certificate_params.certificate_id != p_certificate_params.signed_by) {
      // Find the issuer in the list
      var boolean v_found := false;
      for (var integer v_counter := 0; v_counter < lengthof(p_certificate_details_list); v_counter := v_counter + 1) {
        log("f_finalyse_certificate: compare ", p_certificate_details_list[v_counter].certificate_id, " with ", p_certificate_params.signed_by);
        if (p_certificate_details_list[v_counter].certificate_id == p_certificate_params.signed_by) {
          log("f_finalyse_certificate: Got it");
          v_found := true;
          p_certificate_details.issuer := p_certificate_details_list[v_counter].hashid8;
          p_certificate_details.hash := p_certificate_details_list[v_counter].hash;
          if (p_certificate_params.hash_algorithm == sha256) {
            p_certificate_details.certificate.issuer.sha256AndDigest := p_certificate_details_list[v_counter].hashid8;
          } else if (p_certificate_params.hash_algorithm == sha384) {
            p_certificate_details.certificate.issuer.sha384AndDigest := p_certificate_details_list[v_counter].hashid8;
          } else {
            log("f_finalyse_certificate: Unsupported hash algorithm");
            return -1;
          }
          break;
        }
      } // End of 'for' statement
      if (v_found == false) {
        log("f_finalyse_certificate: issuer not found");
        return -1;
      }
    }
    // Encode the certificate
    p_certificate_details.enc_cert := bit2oct(encvalue(p_certificate_details.certificate));
    // Calculate the whole HashedId8 as defined in IEEE Std 1609.2-20XX Clause 6.4.3 CertificateBase
    if (p_certificate_params.hash_algorithm == sha256) {
      p_certificate_details.hash := f_hashWithSha256(p_certificate_details.enc_cert); // Hash of the whole certificate
      p_certificate_details.hashid8 := f_HashedId8FromSha256(p_certificate_details.hash);
    } else {
      p_certificate_details.hash := f_hashWithSha384(p_certificate_details.enc_cert); // Hash of the whole certificate
      p_certificate_details.hashid8 := f_HashedId8FromSha384(p_certificate_details.hash);
    }
    if (p_certificate_params.certificate_id == p_certificate_params.signed_by) { // Root certificate
      log("f_finalyse_certificate: Root certificate");
      p_certificate_details.issuer := p_certificate_details.hashid8
    }
   
    return 0;
  } // End of function f_finalyse_certificate
 
  function f_store_certificates(
                                in certificate_details_list p_certificate_details_list
                                ) return integer {
    fx_loadCertificates(PX_CERTIFICATE_POOL_PATH, PX_IUT_SEC_CONFIG_NAME);
    for (var integer v_counter := 0; v_counter < lengthof(p_certificate_details_list); v_counter := v_counter + 1) {
      log("f_store_certificates: ", p_certificate_details_list[v_counter]);
      if (ispresent(p_certificate_details_list[v_counter].private_enc_key)) {
        fx_store_certificate(
                             p_certificate_details_list[v_counter].certificate_id,
                             p_certificate_details_list[v_counter].enc_cert,
                             p_certificate_details_list[v_counter].private_key,
                             p_certificate_details_list[v_counter].public_key_x,
                             p_certificate_details_list[v_counter].public_key_y,
                             p_certificate_details_list[v_counter].public_key_compressed,
                             p_certificate_details_list[v_counter].public_key_compressed_mode,
                             p_certificate_details_list[v_counter].hash,
                             p_certificate_details_list[v_counter].hashid8,
                             p_certificate_details_list[v_counter].issuer,
                             p_certificate_details_list[v_counter].private_enc_key,
                             p_certificate_details_list[v_counter].public_enc_key_x,
                             p_certificate_details_list[v_counter].public_enc_key_y,
                             p_certificate_details_list[v_counter].public_enc_key_compressed,
                             p_certificate_details_list[v_counter].public_enc_key_compressed_mode);
      } else {
        fx_store_certificate(
                             p_certificate_details_list[v_counter].certificate_id,
                             p_certificate_details_list[v_counter].enc_cert,
                             p_certificate_details_list[v_counter].private_key,
                             p_certificate_details_list[v_counter].public_key_x,
                             p_certificate_details_list[v_counter].public_key_y,
                             p_certificate_details_list[v_counter].public_key_compressed,
                             p_certificate_details_list[v_counter].public_key_compressed_mode,
                             p_certificate_details_list[v_counter].hash,
                             p_certificate_details_list[v_counter].hashid8,
                             p_certificate_details_list[v_counter].issuer,
                             omit,
                             omit,
                             omit,
                             omit,
                             omit);
      }
    } // End of 'for' statement
   
    return 0;
  } // End of function f_store_certificates
 
} // End of module ItsGenCert_Functions