Skip to content
LibItsSecurity_Functions.ttcn3 36.4 KiB
Newer Older
garciay's avatar
garciay committed
/**
 *  @author   ETSI / STF481
 *  @version  $URL$
 *            $Id$
 *  @desc     Module containing functions for Security Protocol
 *
 */
module LibItsSecurity_Functions {
    // LibItsCommon
    import from LibItsCommon_Functions all;
    
    // LibItsSecurity
    import from LibItsSecurity_TypesAndValues all;
    import from LibItsSecurity_Templates all;
    import from LibItsSecurity_Pixits all;
garciay's avatar
garciay committed
    
    group helpersFunctions {
        
        /**
         * @desc    Produces a 256-bit (32-byte) hash value
         * @param   p_toBeHashedData Data to be used to calculate the hash value
         * @return  The hash value
        function f_hashWithSha256(in octetstring p_toBeHashedData) return Oct32 {
            return fx_hashWithSha256(p_toBeHashedData);
        } // End of function f_hashWithSha256
        
        /**
         * @desc    Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signaturee
         * @param   p_toBeSignedSecuredMessage    The data to be signed
         * @return  The signature value
        function f_signWithEcdsaNistp256WithSha256(in Oct32 p_toBeSignedSecuredMessage) return octetstring {
            return fx_signWithEcdsaNistp256WithSha256(
                p_toBeSignedSecuredMessage,
                PX_TA_CONFIGS[PX_CERTIFICATE_CONFIG_IDX].signingPrivateKey
        } // End of function f_signWithEcdsaNistp256WithSha256

        function f_HashedId8FromSha256(in Oct32 p_hash)
        return HashedId8 {
            return substr(p_hash, 0, 8);
        } // End of function f_HashedId8FromSha256 

        function f_HashedId3FromHashedId8 (in HashedId8 p_hash)
        return HashedId3 {
            return substr(p_hash, 0, 3);
        }  // End of function f_HashedId3FromHashedId8
        
        /**
         * @desc    Verify the signature of the specified data
         * @param   p_toBeVerifiedData          The data to be verified
         * @param   p_signature                 The signature
         * @param   p_ecdsaNistp256PublicKeyX   The public key (x coordinate)
         * @param   p_ecdsaNistp256PublicKeyY   The public key (y coordinate)
         * @return  true on success, false otherwise
         */
        function f_verifyWithEcdsaNistp256WithSha256(
                                                     in octetstring p_toBeVerifiedData, 
                                                     in octetstring p_signature, 
                                                     in octetstring p_ecdsaNistp256PublicKeyX, 
                                                     in octetstring p_ecdsaNistp256PublicKeyY
        ) return boolean {
garciay's avatar
garciay committed
//            log("p_toBeVerifiedData=        ", p_toBeVerifiedData);
//            log("p_signature=               ", p_signature);
//            log("p_ecdsaNistp256PublicKeyX= ", p_ecdsaNistp256PublicKeyX);
//            log("p_ecdsaNistp256PublicKeyY= ", p_ecdsaNistp256PublicKeyY);
            return fx_verifyWithEcdsaNistp256WithSha256(
                p_toBeVerifiedData, 
                p_signature, 
                p_ecdsaNistp256PublicKeyX, 
                p_ecdsaNistp256PublicKeyY);
        } // End of function f_verifyWithEcdsaNistp256WithSha256
        /**
         * @desc    Calculate digest over the certificate
         * @param   p_cert The certificate
         * @see Draft ETSI TS 103 097 V1.1.6 Clause 4.2.13   HashedId8
        function f_calculateDigest(in Certificate p_cert) return HashedId8 {
            var octetstring v_toBeHashedData;
            var octetstring v_hash;
            var integer v_counter;
            
            // Search for digest in the signer_infos field first
            for (v_counter := 0; v_counter < lengthof(p_cert.signer_infos); v_counter := v_counter + 1) {
                if (p_cert.signer_infos[v_counter].type_ == e_certificate_digest_with_ecdsap256) {
                    return p_cert.signer_infos[v_counter].signerInfo.digest;
                }
            } // End of 'for' statement
            // digest not found, compute it 
            v_toBeHashedData := bit2oct(encvalue(p_cert));
            v_hash := f_hashWithSha256(v_toBeHashedData);
            return substr(v_hash, lengthof(v_hash) - 8, 8);
        group hostSignatureHelpers {
            /**
             * @desc Build a template of a secured beacon to be used for the Test Adapter secured beaconing processing
             */
            function f_buildSecuredMessagePayloadToBeSigned()
            return ToBeSignedSecuredMessage {
                // Local variables
                var template (value) ToBeSignedSecuredMessage v_toBeSignedSecuredMessage;
                
                // Build the beacon template
                v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
                    c_security_profileOthers,
                    { // Field HeaderFields
                        m_header_field_signer_info(
                            m_signerInfo_certificate(
                                PX_TA_CONFIGS[PX_CERTIFICATE_CONFIG_IDX].atCertificate
                            ) // End of template m_signerInfo_certificate
                        ), // End of template m_header_field_signer_info
                        m_header_field_generation_time(oct2int('BBBBBBBB'O)),   // To be replaced by TA with current time
                        m_header_field_generation_location(
                            PX_TA_CONFIGS[PX_CERTIFICATE_CONFIG_IDX].location
                        )
                    }, // End of field HeaderFields
                    {
                        m_payload_unsecured(
                            'AAAAAAAAAA'O                                       // To be replaced by TA with real payload
                        )
                    }, // End of field HeaderFields
                    e_signature
                );
                
garciay's avatar
garciay committed
                return valueof(v_toBeSignedSecuredMessage);
            /**
             * @desc This function build and sign the SecureMessage part covered by the signature process
             * @param p_securedMessage      The signed  SecureMessage part
             * @param p_unsecuredPayload    The unsigned payload (e.g. a beacon)
             * @param p_threeDLocation      The ThreeDLocation value
             * @param p_headerFields        Additional HeaderFields
             * @return true on success, false otherwise
             * @verdict Unchanged
             */
            function f_buildGnSecuredCam(
                                         out template (value) SecuredMessage p_securedMessage, 
                                         in octetstring p_unsecuredPayload, 
                                         in ThreeDLocation p_threeDLocation, 
                                         in template (omit) HeaderFields p_headerFields := omit
            ) return boolean {
                
                // Local variables
                var octetstring v_secPayload, v_signature;
                var Oct32 v_hash;
                var template (value) ToBeSignedSecuredMessage v_toBeSignedSecuredMessage;
                 
                // Create SecuredMessage payload to be signed
                v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
                    c_security_profileCAMs,
                    { // Field HeaderFields
                        m_header_field_signer_info(
                            m_signerInfo_certificate(
                                PX_TA_CONFIGS[PX_CERTIFICATE_CONFIG_IDX].atCertificate
                            ) // End of template m_signerInfo_certificate
                        ), // End of template m_header_field_signer_info
                        m_header_field_generation_time(f_getCurrentTime()),
                        m_header_field_generation_location(
                            p_threeDLocation
                        ),
                        m_header_field_message_type(c_messageType_CAM)
                    }, // End of field HeaderFields
                    {
                        m_payload_unsecured(
                            p_unsecuredPayload
                        )
                    }, // End of field HeaderFields
                    e_signature
                );
                log("v_toBeSignedSecuredMessage=", v_toBeSignedSecuredMessage);
                
                // Add additional header fields if any
                if (ispresent(p_headerFields) == true) {
                    var integer v_addItemIndex := lengthof(v_toBeSignedSecuredMessage.header_fields);
                    var integer v_counter;
                    
                    for (v_counter := 0; v_counter < lengthof(p_headerFields); v_counter := v_counter + 1) {
                        v_toBeSignedSecuredMessage.header_fields[v_addItemIndex] := p_headerFields[v_counter];
                        v_addItemIndex := v_addItemIndex + 1;
                    } // End of 'for' statement
                }
                
                v_secPayload := bit2oct(encvalue(v_toBeSignedSecuredMessage));
                log("v_secPayload= ", v_secPayload);
                
                // Calculate the hash of the SecuredMessage payload to be signed
                v_hash := f_hashWithSha256(v_secPayload);
                log("v_hash= ", v_hash);
                
                // Signed payload
                v_signature := f_signWithEcdsaNistp256WithSha256(
                    v_hash
                );
                log("v_signature= ", v_signature);
                p_securedMessage := md_secureMessage_profileCam( // See Clause 7.1   Security profile for CAMs
                    v_toBeSignedSecuredMessage.header_fields,
                    v_toBeSignedSecuredMessage.payload_fields,
                    {
                        m_trailer_field_signature(
                            m_signature(
                                m_ecdsaSignature(
                                    m_eccPointecdsa_nistp256_with_sha256_y_coordinate_only(
                                        substr(v_signature, 2, 32)
                                    ),
                                    substr(v_signature, 34, 32)
                                )
                ); // End of template m_securedMessage_profileCam
            /**
             * @desc This function build and sign the SecureMessage part covered by the signature process
             * @param p_securedMessage      The signed  SecureMessage part
             * @param p_unsecuredPayload    The unsigned payload (e.g. a beacon)
             * @param p_threeDLocation      The ThreeDLocation value
             * @param p_headerFields        Additional HeaderFields
             * @return true on success, false otherwise
             * @verdict Unchanged
             */
            function f_buildGnSecuredDenm(
                                          out template (value) SecuredMessage p_securedMessage, 
                                          in octetstring p_unsecuredPayload, 
                                          in ThreeDLocation p_threeDLocation, 
                                          in template (omit) HeaderFields p_headerFields := omit
            ) return boolean {
                
                // Local variables
                var octetstring v_secPayload, v_signature;
                var Oct32 v_hash;
                var template (value) ToBeSignedSecuredMessage v_toBeSignedSecuredMessage;
                 
                // Create SecuredMessage payload to be signed
                v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
                    c_security_profileDENMs,
                    { // Field HeaderFields
                        m_header_field_signer_info(
                            m_signerInfo_certificate(
                                PX_TA_CONFIGS[PX_CERTIFICATE_CONFIG_IDX].atCertificate
                            ) // End of template m_signerInfo_certificate
                        ), // End of template m_header_field_signer_info
                        m_header_field_generation_time(f_getCurrentTime()),
                        m_header_field_generation_location(
                            p_threeDLocation
                        ),
                        m_header_field_message_type(c_messageType_DENM)
                    }, // End of field HeaderFields
                    {
                        m_payload_unsecured(
                            p_unsecuredPayload
                        )
                    }, // End of field HeaderFields
                    e_signature
                );
                // Add additional header fields if any
                if (ispresent(p_headerFields) == true) {
                    var integer v_addItemIndex := lengthof(v_toBeSignedSecuredMessage.header_fields);
                    var integer v_counter;
                    
                    for (v_counter := 0; v_counter < lengthof(p_headerFields); v_counter := v_counter + 1) {
                        v_toBeSignedSecuredMessage.header_fields[v_addItemIndex] := p_headerFields[v_counter];
                        v_addItemIndex := v_addItemIndex + 1;
                    } // End of 'for' statement
                }
                log("v_toBeSignedSecuredMessage= ", v_toBeSignedSecuredMessage);
                
                v_secPayload := bit2oct(encvalue(v_toBeSignedSecuredMessage));
                
                // Calculate the hash of the SecuredMessage payload to be signed
                v_hash := f_hashWithSha256(v_secPayload);
                
                // Signed payload
                v_signature := f_signWithEcdsaNistp256WithSha256(
                    v_hash
                );
                
                p_securedMessage := md_secureMessage_profileDenm( // See Clause 7.2   Security profile for DENMs
                    v_toBeSignedSecuredMessage.header_fields,
                    v_toBeSignedSecuredMessage.payload_fields,
                    {
                        m_trailer_field_signature(
                            m_signature(
                                m_ecdsaSignature(
                                    m_eccPointecdsa_nistp256_with_sha256_y_coordinate_only(
                                        substr(v_signature, 2, 32)
                                    ),
                                    substr(v_signature, 34, 32)
                                )
                ); // End of template m_securedMessage_profileDenm
                
                return true;
            } // End of function f_buildGnSecuredDenm
            /**
             * @desc This function build and sign the SecureMessage part covered by the signature process
             * @param p_securedMessage      The signed  SecureMessage part
             * @param p_unsecuredPayload    The unsigned payload (e.g. a beacon)
             * @param p_threeDLocation      The ThreeDLocation value
             * @param p_headerFields        Additional HeaderFields
             * @return true on success, false otherwise
             * @verdict Unchanged
             */
            function f_buildGnSecuredOtherMessage(
                                                  out template (value) SecuredMessage p_securedMessage, 
                                                  in octetstring p_unsecuredPayload, 
                                                  in ThreeDLocation p_threeDLocation, 
                                                  in template (omit) HeaderFields p_headerFields := omit
            ) return boolean {
                
                // Local variables
                var octetstring v_secPayload, v_signature;
                var Oct32 v_hash;
                var template (value) ToBeSignedSecuredMessage v_toBeSignedSecuredMessage;
                 
                // Create SecuredMessage payload to be signed
                v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
                    c_security_profileOthers,
                    { // Field HeaderFields
                        m_header_field_signer_info(
                            m_signerInfo_certificate(
                                PX_TA_CONFIGS[PX_CERTIFICATE_CONFIG_IDX].atCertificate
                            ) // End of template m_signerInfo_certificate
                        ), // End of template m_header_field_signer_info
                        m_header_field_generation_time(f_getCurrentTime()),
                        m_header_field_generation_location(
                            p_threeDLocation
                        )
                    }, // End of field HeaderFields
                    {
                        m_payload_unsecured(
                            p_unsecuredPayload
                        )
                    }, // End of field HeaderFields
                    e_signature
                );
                // Add additional header fields if any
                if (ispresent(p_headerFields) == true) {
                    var integer v_addItemIndex := lengthof(v_toBeSignedSecuredMessage.header_fields);
                    var integer v_counter;
                    
                    for (v_counter := 0; v_counter < lengthof(p_headerFields); v_counter := v_counter + 1) {
                        v_toBeSignedSecuredMessage.header_fields[v_addItemIndex] := p_headerFields[v_counter];
                        v_addItemIndex := v_addItemIndex + 1;
                    } // End of 'for' statement
                }
                log("v_toBeSignedSecuredMessage= ", v_toBeSignedSecuredMessage);
                
                v_secPayload := bit2oct(encvalue(v_toBeSignedSecuredMessage));
                
                // Calculate the hash of the SecuredMessage payload to be signed
                v_hash := f_hashWithSha256(v_secPayload);
                
                // Signed payload
                v_signature := f_signWithEcdsaNistp256WithSha256(
                    v_hash
                );
                
                p_securedMessage := md_securedMessage_profileOther( // See Clause 7.3   Generic security profile for other signed messages
                    v_toBeSignedSecuredMessage.header_fields,
                    v_toBeSignedSecuredMessage.payload_fields,
                    {
                        m_trailer_field_signature(
                            m_signature(
                                m_ecdsaSignature(
                                    m_eccPointecdsa_nistp256_with_sha256_y_coordinate_only(
                                        substr(v_signature, 2, 32)
                                    ),
                                    substr(v_signature, 34, 32)
                                )
                ); // End of template md_securedMessage_profileOther
                
                return true;
            } // End of function f_buildGnSecuredOtherMessage
        } // End of group hostSignatureHelpers
        
        group deviceSignatureHelpers {
             
garciay's avatar
garciay committed
            /**
             * @desc Verify the signature of the provided certificate
             * @param p_certificateToBeVerified Certificate to be verified
             * @param p_publicKey               Public key to verify the certificate signature
garciay's avatar
garciay committed
             * @return true on success, false otherwise
garciay's avatar
garciay committed
             */
            function f_verifyCertificateSignatureWithPublicKey(
                                                               in template (value) Certificate p_certificateToBeVerified,
                                                               in template (value) PublicKey   p_publicKey 
            ) return boolean {
                // Local variables
                var octetstring toBeVerifiedData;
                var octetstring v_signature;
                var boolean v_result := false;
                var template (value) ToBeSignedCertificate v_toBeSignedCertificate;
                
                // Create Certificate payload to be verified
                v_toBeSignedCertificate := m_toBeSignedCertificate(p_certificateToBeVerified);
                toBeVerifiedData := bit2oct(encvalue(v_toBeSignedCertificate));
                
                // Build the signature
                v_signature := 
                    '0000'O & 
garciay's avatar
garciay committed
                    valueof(p_certificateToBeVerified.signature_.signature_.ecdsa_signature.r.x) & 
                    valueof(p_certificateToBeVerified.signature_.signature_.ecdsa_signature.s);
                
                // Verify the certificate
                v_result := f_verifyWithEcdsaNistp256WithSha256(
                    toBeVerifiedData,
                    v_signature,
garciay's avatar
garciay committed
                    valueof(p_publicKey.public_key.eccPoint.x),
                    valueof(p_publicKey.public_key.eccPoint.y.y)
                return v_result;
            } // End of finction f_verifyCertificateSignatureWithPublicKey
            /**
             * @desc Verify the signature of the provided secured message
             * @param p_certificateToBeVerified Certificate to be verified
             * @param p_issuingCertificate      Issuing certificate
             * @return true on success, false otherwise
             * @verdict 
             */
            function f_verifyCertificateSignatureWithIssuingCertificate(
                                                                        in template (value) Certificate p_certificateToBeVerified,
                                                                        in template (value) Certificate p_issuingCertificate 
                var integer v_counter;
                
                for (v_counter := 0; v_counter < lengthof(p_issuingCertificate.subject_attributes); v_counter := v_counter + 1) {
garciay's avatar
garciay committed
                    if (valueof(p_issuingCertificate.subject_attributes[v_counter].type_) == e_verification_key) {
                        return f_verifyCertificateSignatureWithPublicKey(
                            p_certificateToBeVerified,
                            p_issuingCertificate.subject_attributes[v_counter].attribute.key);
                    }
                } // End of 'for' statement
                
                return false;
            } // End of function f_verifyCertificateSignatureWithIssuingCertificate
            
            /**
             * @desc Verify the signature of the provided secured message
             * @param p_securedMessage  The message to be verified
             * @param p_publicKey       The ECDSA public key to verify a signature 
             * @param p_certificate     Certificate to be used to verify the message
             * @return true on success, false otherwise
            function f_verifyGnSecuredMessageSignatureWithPublicKey(
                                                                    in template (value) SecuredMessage p_securedMessage,
                                                                    in template (value) PublicKey p_publicKey 
            ) return boolean {
                
                // Local variables
                var octetstring v_secPayload;
                var octetstring v_signedData;
                var Oct32 v_hash;
                var integer v_counter;
                var boolean v_result := false;
                var template (value) ToBeSignedSecuredMessage v_toBeSignedSecuredMessage;
                log(">>> f_verifyGnSecuredMessageSignatureWithPublicKey: ", p_securedMessage);
                
                // Create SecuredMessage payload to be signed
                v_toBeSignedSecuredMessage := m_toBeSignedSecuredMessage(
garciay's avatar
garciay committed
                    valueof(p_securedMessage).security_profile,
                    p_securedMessage.header_fields, 
                    p_securedMessage.payload_fields, 
                    e_signature
                );
                 
                v_secPayload := bit2oct(encvalue(v_toBeSignedSecuredMessage));
                log("f_verifyGnSecuredMessageSignatureWithPublicKey: v_secPayload=", v_secPayload);
                
                // Calculate the hash of the SecuredMessage payload to be signed
                v_hash := fx_hashWithSha256(v_secPayload);
                log("f_verifyGnSecuredMessageSignatureWithPublicKey: v_hash=", v_hash);
                
                // Verify payload
                for (v_counter := 0; v_counter < lengthof(p_securedMessage.trailer_fields); v_counter := v_counter + 1) {
                    if (
garciay's avatar
garciay committed
                        (valueof(p_securedMessage).trailer_fields[v_counter].type_ == e_signature) and 
                        (valueof(p_securedMessage).trailer_fields[v_counter].trailerField.signature_.algorithm == e_ecdsa_nistp256_with_sha256)
                    ) {
                        v_signedData := 
                            '0000'O & 
garciay's avatar
garciay committed
                            valueof(p_securedMessage).trailer_fields[v_counter].trailerField.signature_.signature_.ecdsa_signature.r.x & 
                            valueof(p_securedMessage).trailer_fields[v_counter].trailerField.signature_.signature_.ecdsa_signature.s;
                        v_result := f_verifyWithEcdsaNistp256WithSha256(
                            v_hash,
                            v_signedData,
garciay's avatar
garciay committed
                            valueof(p_publicKey).public_key.eccPoint.x,
                            valueof(p_publicKey).public_key.eccPoint.y.y
                        );
                    }
                } // End of 'for' statement
                
                return v_result;
            } // End of function f_verifyCertificateSignatureWithPublicKey
            
            /**
             * @desc Verify the signature of the provided secured message
             * @param p_securedMessage
             * @param p_certificate     Certificate to be used to verify the message
             * @return true on success, false otherwise
             * @verdict 
             */
            function f_verifyGnSecuredMessageSignatureWithCertificate(
                                                                      in template (value) SecuredMessage p_securedMessage,
                                                                      in template (value) Certificate p_certificate 
                var integer v_counter;
                
                for (v_counter := 0; v_counter < lengthof(p_certificate.subject_attributes); v_counter := v_counter + 1) {
                    log("f_verifyGnSecuredMessageSignatureWithCertificate: processing ", p_certificate.subject_attributes[v_counter]);
garciay's avatar
garciay committed
                    if (valueof(p_certificate).subject_attributes[v_counter].type_ == e_verification_key) {
                        return f_verifyGnSecuredMessageSignatureWithPublicKey(
                            p_securedMessage,
                            p_certificate.subject_attributes[v_counter].attribute.key);
                    }
                } // End of 'for' statement
                
                return false;
            } // End of function f_verifyGnSecuredOtherMessageWithDeviceCertificate 
        } // End of group deviceSignatureHelpers
filatov's avatar
filatov committed
        group messageGetters {
garciay's avatar
garciay committed
             * @desc    return SecuredMessage header field of given type or null if none 
             * @param   p_msg the SecuredMessage
             * @param   p_type header field type
             * @return  HeaderField of given type if any or null
             */
            function f_getMsgHeaderField(
                                         in  template (value) SecuredMessage p_securedMessage, 
                                         in  HeaderFieldType p_headerFieldType,
                                         out HeaderField p_return
            ) return boolean {
                var integer v_length := lengthof(p_securedMessage.header_fields);
                
                for (var integer i := 0; i < v_length; i := i + 1) {
                    if (valueof(p_securedMessage).header_fields[i].type_ == p_headerFieldType) {
                        p_return := valueof(p_securedMessage).header_fields[i];
                        return true; 
            }
            
            /**
             * @desc    return SignerInfo SecuredMessage field
             */
            function f_getMsgSignerInfo (
garciay's avatar
garciay committed
                                         in template (value) SecuredMessage p_securedMessage,
garciay's avatar
garciay committed
                                         out SignerInfo p_signerInfo
            ) return boolean {
                var HeaderField v_hf;
                if(f_getMsgHeaderField(p_securedMessage, e_signer_info, v_hf)){
                    if(isbound(v_hf.headerField.signer)){
                        p_signerInfo := v_hf.headerField.signer;
                        return true;
                    }
garciay's avatar
garciay committed
            
filatov's avatar
filatov committed
        }// End of group messageGetters
        
        group certificateGetters {
            
            function f_getCertificateValidityRestriction(
                                                         in template (value) Certificate p_cert, 
                                                         in ValidityRestrictionType p_type,
                                                         out ValidityRestriction p_return
            ) return boolean {
                for (var integer i := 0; i < lengthof(p_cert.validity_restrictions); i := i + 1) {
                    if (valueof(p_cert).validity_restrictions[i].type_ == p_type ) {
                        p_return := valueof(p_cert).validity_restrictions[i];
                        return true;
filatov's avatar
filatov committed
                    }
                }
filatov's avatar
filatov committed
            }
            
            function f_getCertificateSignerInfo (
                                                 in template (value) Certificate p_cert,
                                                 out SignerInfo p_si 
            ) return boolean {
                if(    isbound(valueof(p_cert).signer_infos)
                   and lengthof(p_cert.signer_infos) > 0) {
                       p_si := valueof(p_cert).signer_infos[0];
                       return true;
filatov's avatar
filatov committed
                }
filatov's avatar
filatov committed
            }
            
filatov's avatar
filatov committed
        }// End of group certificateGetters
filatov's avatar
filatov committed
        group CertRequests{
            function f_askForCertificate (in template (value) HashedId8 p_digest) {
                // Send CAM message with insert the request_unrecognized_certificate
                // header containing specified digest
/*  TODO: Waiting Alex to understand how to send message
                var SecuredMessage v_msg;
filatov's avatar
filatov committed
                
                if ( f_buildGnSecuredCam (v_msg,
                                          in octetstring p_unsecuredPayload, 
                                          in ThreeDLocation p_threeDLocation, 
                                          in template (omit) HeaderFields p_headerFileds := omit
                )) {
                    
                    
                }
*/                
filatov's avatar
filatov committed
        } // End of group CertRequests 
    
    } // End of group helpersFunctions

    group externalFunctions {
        
        /**
         * @desc    Produces a 256-bit (32-byte) hash value
         * @param   p_toBeHashedData Data to be used to calculate the hash value
         * @return  The hash value
         */
        external function fx_hashWithSha256(in octetstring p_toBeHashedData) return Oct32;
        
        /**
         * @desc    Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signaturee
         * @param   p_toBeSignedSecuredMessage    The data to be signed
         * @param   p_privateKey        The private key
         * @return  The signature value
         */
        external function fx_signWithEcdsaNistp256WithSha256(in octetstring p_toBeSignedSecuredMessage, in octetstring/*UInt64*/ p_privateKey) return octetstring;
        
        /**
         * @desc    Verify the signature of the specified data
         * @param   p_toBeVerifiedData          The data to be verified
         * @param   p_signature                 The signature
         * @param   p_ecdsaNistp256PublicKeyX   The public key (x coordinate)
         * @param   p_ecdsaNistp256PublicKeyY   The public key (y coordinate)
         * @return  true on success, false otherwise
         */
garciay's avatar
garciay committed
        external function fx_verifyWithEcdsaNistp256WithSha256(in octetstring p_toBeVerifiedData, in octetstring p_signature, in octetstring p_ecdsaNistp256PublicKeyX, in octetstring p_ecdsaNistp256PublicKeyY) return boolean;
         * @desc    Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm.
         *          This function should not be used by the ATS
         * @param   p_privateKey    The new private key value
         * @param   p_publicKeyX    The new public key value (x coordinate)
         * @param   p_publicKeyX    The new public key value (y coordinate)
         * @return  true on success, false otherwise
         */
garciay's avatar
garciay committed
        external function fx_generateKeyPair(out octetstring/*UInt64*/ p_privateKey, out octetstring p_publicKeyX, out octetstring p_publicKeyY) return boolean;
        
    } // End of group externalFunctions
    
filatov's avatar
filatov committed
    group geometryFunctions {
        
        /**
         * @desc    Check that given location is valid
         * @param   p_location    location to be checked
         * @return  true on success, false otherwise
         */
        function f_isValidTwoDLocation(in template (value) TwoDLocation p_location
        ) return boolean {
garciay's avatar
garciay committed
            return  valueof(p_location).longitude != c_maxLongitude+1 
                and valueof(p_location).latitude != c_maxLatitude+1; 
filatov's avatar
filatov committed
        }
filatov's avatar
filatov committed
        /**
         * @desc    Check that two given rectanlular regions are intersected
         *          Note: Regions must be normalized(northwest.latitude >= southeast.latitude)
         *          TODO: Add case when 
         * @param   p_r1    Region 1
         * @param   p_r2    Region 2
         * 
         * @return  true on success, false otherwise
         */
        function f_isRectangularRegionsIntersected(in template (value) RectangularRegion p_r1,
                                                   in template (value) RectangularRegion p_r2
        ) return boolean {                                           
garciay's avatar
garciay committed
            return not (    valueof(p_r2).northwest.longitude > valueof(p_r1).southeast.longitude
                         or valueof(p_r2).southeast.longitude < valueof(p_r1).northwest.longitude
                         or valueof(p_r2).southeast.latitude  > valueof(p_r1).northwest.latitude
                         or valueof(p_r2).northwest.latitude  < valueof(p_r1).southeast.latitude );
filatov's avatar
filatov committed
        }
        
        function f_isContinuousRectangularRegions(in template (value) RectangularRegions regions
        ) return boolean {
filatov's avatar
filatov committed
            // TODO: call external function
filatov's avatar
filatov committed
            return true;
        }
        function f_isRectangularRegionsInside(in template (value) RectangularRegions p_parent,
                                              in template (value) RectangularRegions p_region
        ) return boolean {
filatov's avatar
filatov committed
            // TODO: convert rectangular regions to polygons and check polygons 
            return true;
        }
        
        /**
         * @desc    Check that given polygon doesn't have neither self-intersections no holes.
         * @param   p_region   Polygonal Region
         * @return  true on success, false otherwise
         */
        function f_isValidPolygonalRegion(in template (value) PolygonalRegion p_region
        ) return boolean {
            // TODO: call external function
filatov's avatar
filatov committed

        function f_isPolygonalRegionInside(in template (value) PolygonalRegion p_parent,
                                           in template (value) PolygonalRegion p_region
        ) return boolean {
            // TODO: call external function
            return true;
        }
filatov's avatar
filatov committed
    }
    
garciay's avatar
garciay committed
} // End of module LibItsSecurity_Functions