first commit
This commit is contained in:
commit
ea4074574b
|
@ -0,0 +1 @@
|
|||
/target
|
|
@ -0,0 +1,52 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<DBN-PSQL>
|
||||
<case-options enabled="true">
|
||||
<option name="KEYWORD_CASE" value="lower" />
|
||||
<option name="FUNCTION_CASE" value="lower" />
|
||||
<option name="PARAMETER_CASE" value="lower" />
|
||||
<option name="DATATYPE_CASE" value="lower" />
|
||||
<option name="OBJECT_CASE" value="preserve" />
|
||||
</case-options>
|
||||
<formatting-settings enabled="false" />
|
||||
</DBN-PSQL>
|
||||
<DBN-SQL>
|
||||
<case-options enabled="true">
|
||||
<option name="KEYWORD_CASE" value="lower" />
|
||||
<option name="FUNCTION_CASE" value="lower" />
|
||||
<option name="PARAMETER_CASE" value="lower" />
|
||||
<option name="DATATYPE_CASE" value="lower" />
|
||||
<option name="OBJECT_CASE" value="preserve" />
|
||||
</case-options>
|
||||
<formatting-settings enabled="false">
|
||||
<option name="STATEMENT_SPACING" value="one_line" />
|
||||
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
|
||||
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
|
||||
</formatting-settings>
|
||||
</DBN-SQL>
|
||||
<DBN-PSQL>
|
||||
<case-options enabled="true">
|
||||
<option name="KEYWORD_CASE" value="lower" />
|
||||
<option name="FUNCTION_CASE" value="lower" />
|
||||
<option name="PARAMETER_CASE" value="lower" />
|
||||
<option name="DATATYPE_CASE" value="lower" />
|
||||
<option name="OBJECT_CASE" value="preserve" />
|
||||
</case-options>
|
||||
<formatting-settings enabled="false" />
|
||||
</DBN-PSQL>
|
||||
<DBN-SQL>
|
||||
<case-options enabled="true">
|
||||
<option name="KEYWORD_CASE" value="lower" />
|
||||
<option name="FUNCTION_CASE" value="lower" />
|
||||
<option name="PARAMETER_CASE" value="lower" />
|
||||
<option name="DATATYPE_CASE" value="lower" />
|
||||
<option name="OBJECT_CASE" value="preserve" />
|
||||
</case-options>
|
||||
<formatting-settings enabled="false">
|
||||
<option name="STATEMENT_SPACING" value="one_line" />
|
||||
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
|
||||
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
|
||||
</formatting-settings>
|
||||
</DBN-SQL>
|
||||
</code_scheme>
|
||||
</component>
|
|
@ -0,0 +1,453 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DBNavigator.Project.DataEditorManager">
|
||||
<record-view-column-sorting-type value="BY_INDEX" />
|
||||
<value-preview-text-wrapping value="true" />
|
||||
<value-preview-pinned value="false" />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.DataExportManager">
|
||||
<export-instructions>
|
||||
<create-header value="true" />
|
||||
<quote-values-containing-separator value="true" />
|
||||
<quote-all-values value="false" />
|
||||
<value-separator value="" />
|
||||
<file-name value="" />
|
||||
<file-location value="" />
|
||||
<scope value="GLOBAL" />
|
||||
<destination value="FILE" />
|
||||
<format value="EXCEL" />
|
||||
<charset value="windows-1252" />
|
||||
</export-instructions>
|
||||
</component>
|
||||
<component name="DBNavigator.Project.DatabaseBrowserManager">
|
||||
<autoscroll-to-editor value="false" />
|
||||
<autoscroll-from-editor value="true" />
|
||||
<show-object-properties value="true" />
|
||||
<loaded-nodes />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.DatabaseFileManager">
|
||||
<open-files />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.EditorStateManager">
|
||||
<last-used-providers />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.MethodExecutionManager">
|
||||
<method-browser />
|
||||
<execution-history>
|
||||
<group-entries value="true" />
|
||||
<execution-inputs />
|
||||
</execution-history>
|
||||
<argument-values-cache />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.ObjectDependencyManager">
|
||||
<last-used-dependency-type value="INCOMING" />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.ObjectQuickFilterManager">
|
||||
<last-used-operator value="EQUAL" />
|
||||
<filters />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.ScriptExecutionManager" clear-outputs="true">
|
||||
<recently-used-interfaces />
|
||||
</component>
|
||||
<component name="DBNavigator.Project.Settings">
|
||||
<connections />
|
||||
<browser-settings>
|
||||
<general>
|
||||
<display-mode value="TABBED" />
|
||||
<navigation-history-size value="100" />
|
||||
<show-object-details value="false" />
|
||||
</general>
|
||||
<filters>
|
||||
<object-type-filter>
|
||||
<object-type name="SCHEMA" enabled="true" />
|
||||
<object-type name="USER" enabled="true" />
|
||||
<object-type name="ROLE" enabled="true" />
|
||||
<object-type name="PRIVILEGE" enabled="true" />
|
||||
<object-type name="CHARSET" enabled="true" />
|
||||
<object-type name="TABLE" enabled="true" />
|
||||
<object-type name="VIEW" enabled="true" />
|
||||
<object-type name="MATERIALIZED_VIEW" enabled="true" />
|
||||
<object-type name="NESTED_TABLE" enabled="true" />
|
||||
<object-type name="COLUMN" enabled="true" />
|
||||
<object-type name="INDEX" enabled="true" />
|
||||
<object-type name="CONSTRAINT" enabled="true" />
|
||||
<object-type name="DATASET_TRIGGER" enabled="true" />
|
||||
<object-type name="DATABASE_TRIGGER" enabled="true" />
|
||||
<object-type name="SYNONYM" enabled="true" />
|
||||
<object-type name="SEQUENCE" enabled="true" />
|
||||
<object-type name="PROCEDURE" enabled="true" />
|
||||
<object-type name="FUNCTION" enabled="true" />
|
||||
<object-type name="PACKAGE" enabled="true" />
|
||||
<object-type name="TYPE" enabled="true" />
|
||||
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
|
||||
<object-type name="ARGUMENT" enabled="true" />
|
||||
<object-type name="DIMENSION" enabled="true" />
|
||||
<object-type name="CLUSTER" enabled="true" />
|
||||
<object-type name="DBLINK" enabled="true" />
|
||||
</object-type-filter>
|
||||
</filters>
|
||||
<sorting>
|
||||
<object-type name="COLUMN" sorting-type="NAME" />
|
||||
<object-type name="FUNCTION" sorting-type="NAME" />
|
||||
<object-type name="PROCEDURE" sorting-type="NAME" />
|
||||
<object-type name="ARGUMENT" sorting-type="POSITION" />
|
||||
</sorting>
|
||||
<default-editors>
|
||||
<object-type name="VIEW" editor-type="SELECTION" />
|
||||
<object-type name="PACKAGE" editor-type="SELECTION" />
|
||||
<object-type name="TYPE" editor-type="SELECTION" />
|
||||
</default-editors>
|
||||
</browser-settings>
|
||||
<navigation-settings>
|
||||
<lookup-filters>
|
||||
<lookup-objects>
|
||||
<object-type name="SCHEMA" enabled="true" />
|
||||
<object-type name="USER" enabled="false" />
|
||||
<object-type name="ROLE" enabled="false" />
|
||||
<object-type name="PRIVILEGE" enabled="false" />
|
||||
<object-type name="CHARSET" enabled="false" />
|
||||
<object-type name="TABLE" enabled="true" />
|
||||
<object-type name="VIEW" enabled="true" />
|
||||
<object-type name="MATERIALIZED VIEW" enabled="true" />
|
||||
<object-type name="NESTED TABLE" enabled="false" />
|
||||
<object-type name="COLUMN" enabled="false" />
|
||||
<object-type name="INDEX" enabled="true" />
|
||||
<object-type name="CONSTRAINT" enabled="true" />
|
||||
<object-type name="DATASET TRIGGER" enabled="true" />
|
||||
<object-type name="DATABASE TRIGGER" enabled="true" />
|
||||
<object-type name="SYNONYM" enabled="false" />
|
||||
<object-type name="SEQUENCE" enabled="true" />
|
||||
<object-type name="PROCEDURE" enabled="true" />
|
||||
<object-type name="FUNCTION" enabled="true" />
|
||||
<object-type name="PACKAGE" enabled="true" />
|
||||
<object-type name="TYPE" enabled="true" />
|
||||
<object-type name="TYPE ATTRIBUTE" enabled="false" />
|
||||
<object-type name="ARGUMENT" enabled="false" />
|
||||
<object-type name="DIMENSION" enabled="false" />
|
||||
<object-type name="CLUSTER" enabled="false" />
|
||||
<object-type name="DBLINK" enabled="true" />
|
||||
</lookup-objects>
|
||||
<force-database-load value="false" />
|
||||
<prompt-connection-selection value="true" />
|
||||
<prompt-schema-selection value="true" />
|
||||
</lookup-filters>
|
||||
</navigation-settings>
|
||||
<dataset-grid-settings>
|
||||
<general>
|
||||
<enable-zooming value="true" />
|
||||
<enable-column-tooltip value="true" />
|
||||
</general>
|
||||
<sorting>
|
||||
<nulls-first value="true" />
|
||||
<max-sorting-columns value="4" />
|
||||
</sorting>
|
||||
<tracking-columns>
|
||||
<columnNames value="" />
|
||||
<visible value="true" />
|
||||
<editable value="false" />
|
||||
</tracking-columns>
|
||||
</dataset-grid-settings>
|
||||
<dataset-editor-settings>
|
||||
<text-editor-popup>
|
||||
<active value="false" />
|
||||
<active-if-empty value="false" />
|
||||
<data-length-threshold value="100" />
|
||||
<popup-delay value="1000" />
|
||||
</text-editor-popup>
|
||||
<values-actions-popup>
|
||||
<show-popup-button value="true" />
|
||||
<element-count-threshold value="1000" />
|
||||
<data-length-threshold value="250" />
|
||||
</values-actions-popup>
|
||||
<general>
|
||||
<fetch-block-size value="100" />
|
||||
<fetch-timeout value="30" />
|
||||
<trim-whitespaces value="true" />
|
||||
<convert-empty-strings-to-null value="true" />
|
||||
<select-content-on-cell-edit value="true" />
|
||||
<large-value-preview-active value="true" />
|
||||
</general>
|
||||
<filters>
|
||||
<prompt-filter-dialog value="true" />
|
||||
<default-filter-type value="BASIC" />
|
||||
</filters>
|
||||
<qualified-text-editor text-length-threshold="300">
|
||||
<content-types>
|
||||
<content-type name="Text" enabled="true" />
|
||||
<content-type name="Properties" enabled="true" />
|
||||
<content-type name="XML" enabled="true" />
|
||||
<content-type name="DTD" enabled="true" />
|
||||
<content-type name="HTML" enabled="true" />
|
||||
<content-type name="XHTML" enabled="true" />
|
||||
<content-type name="Java" enabled="true" />
|
||||
<content-type name="Groovy" enabled="true" />
|
||||
<content-type name="YAML" enabled="true" />
|
||||
<content-type name="Manifest" enabled="true" />
|
||||
</content-types>
|
||||
</qualified-text-editor>
|
||||
<record-navigation>
|
||||
<navigation-target value="VIEWER" />
|
||||
</record-navigation>
|
||||
</dataset-editor-settings>
|
||||
<code-editor-settings>
|
||||
<general>
|
||||
<show-object-navigation-gutter value="false" />
|
||||
<show-spec-declaration-navigation-gutter value="true" />
|
||||
<enable-spellchecking value="true" />
|
||||
<enable-reference-spellchecking value="false" />
|
||||
</general>
|
||||
<confirmations>
|
||||
<save-changes value="false" />
|
||||
<revert-changes value="true" />
|
||||
</confirmations>
|
||||
</code-editor-settings>
|
||||
<code-completion-settings>
|
||||
<filters>
|
||||
<basic-filter>
|
||||
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||
<filter-element type="OBJECT" id="role" selected="true" />
|
||||
<filter-element type="OBJECT" id="user" selected="true" />
|
||||
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||
<user-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</user-schema>
|
||||
<public-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="false" />
|
||||
<filter-element type="OBJECT" id="view" selected="false" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="false" />
|
||||
<filter-element type="OBJECT" id="index" selected="false" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="false" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="false" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="false" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="false" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="false" />
|
||||
<filter-element type="OBJECT" id="function" selected="false" />
|
||||
<filter-element type="OBJECT" id="package" selected="false" />
|
||||
<filter-element type="OBJECT" id="type" selected="false" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="false" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="false" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="false" />
|
||||
</public-schema>
|
||||
<any-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</any-schema>
|
||||
</basic-filter>
|
||||
<extended-filter>
|
||||
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="function" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
|
||||
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
|
||||
<filter-element type="OBJECT" id="schema" selected="true" />
|
||||
<filter-element type="OBJECT" id="user" selected="true" />
|
||||
<filter-element type="OBJECT" id="role" selected="true" />
|
||||
<filter-element type="OBJECT" id="privilege" selected="true" />
|
||||
<user-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</user-schema>
|
||||
<public-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</public-schema>
|
||||
<any-schema>
|
||||
<filter-element type="OBJECT" id="table" selected="true" />
|
||||
<filter-element type="OBJECT" id="view" selected="true" />
|
||||
<filter-element type="OBJECT" id="materialized view" selected="true" />
|
||||
<filter-element type="OBJECT" id="index" selected="true" />
|
||||
<filter-element type="OBJECT" id="constraint" selected="true" />
|
||||
<filter-element type="OBJECT" id="trigger" selected="true" />
|
||||
<filter-element type="OBJECT" id="synonym" selected="true" />
|
||||
<filter-element type="OBJECT" id="sequence" selected="true" />
|
||||
<filter-element type="OBJECT" id="procedure" selected="true" />
|
||||
<filter-element type="OBJECT" id="function" selected="true" />
|
||||
<filter-element type="OBJECT" id="package" selected="true" />
|
||||
<filter-element type="OBJECT" id="type" selected="true" />
|
||||
<filter-element type="OBJECT" id="dimension" selected="true" />
|
||||
<filter-element type="OBJECT" id="cluster" selected="true" />
|
||||
<filter-element type="OBJECT" id="dblink" selected="true" />
|
||||
</any-schema>
|
||||
</extended-filter>
|
||||
</filters>
|
||||
<sorting enabled="true">
|
||||
<sorting-element type="RESERVED_WORD" id="keyword" />
|
||||
<sorting-element type="RESERVED_WORD" id="datatype" />
|
||||
<sorting-element type="OBJECT" id="column" />
|
||||
<sorting-element type="OBJECT" id="table" />
|
||||
<sorting-element type="OBJECT" id="view" />
|
||||
<sorting-element type="OBJECT" id="materialized view" />
|
||||
<sorting-element type="OBJECT" id="index" />
|
||||
<sorting-element type="OBJECT" id="constraint" />
|
||||
<sorting-element type="OBJECT" id="trigger" />
|
||||
<sorting-element type="OBJECT" id="synonym" />
|
||||
<sorting-element type="OBJECT" id="sequence" />
|
||||
<sorting-element type="OBJECT" id="procedure" />
|
||||
<sorting-element type="OBJECT" id="function" />
|
||||
<sorting-element type="OBJECT" id="package" />
|
||||
<sorting-element type="OBJECT" id="type" />
|
||||
<sorting-element type="OBJECT" id="dimension" />
|
||||
<sorting-element type="OBJECT" id="cluster" />
|
||||
<sorting-element type="OBJECT" id="dblink" />
|
||||
<sorting-element type="OBJECT" id="schema" />
|
||||
<sorting-element type="OBJECT" id="role" />
|
||||
<sorting-element type="OBJECT" id="user" />
|
||||
<sorting-element type="RESERVED_WORD" id="function" />
|
||||
<sorting-element type="RESERVED_WORD" id="parameter" />
|
||||
</sorting>
|
||||
<format>
|
||||
<enforce-code-style-case value="true" />
|
||||
</format>
|
||||
</code-completion-settings>
|
||||
<execution-engine-settings>
|
||||
<statement-execution>
|
||||
<fetch-block-size value="100" />
|
||||
<execution-timeout value="20" />
|
||||
<debug-execution-timeout value="600" />
|
||||
<focus-result value="false" />
|
||||
<prompt-execution value="false" />
|
||||
</statement-execution>
|
||||
<script-execution>
|
||||
<command-line-interfaces />
|
||||
<execution-timeout value="300" />
|
||||
</script-execution>
|
||||
<method-execution>
|
||||
<execution-timeout value="30" />
|
||||
<debug-execution-timeout value="600" />
|
||||
<parameter-history-size value="10" />
|
||||
</method-execution>
|
||||
</execution-engine-settings>
|
||||
<operation-settings>
|
||||
<transactions>
|
||||
<uncommitted-changes>
|
||||
<on-project-close value="ASK" />
|
||||
<on-disconnect value="ASK" />
|
||||
<on-autocommit-toggle value="ASK" />
|
||||
</uncommitted-changes>
|
||||
<multiple-uncommitted-changes>
|
||||
<on-commit value="ASK" />
|
||||
<on-rollback value="ASK" />
|
||||
</multiple-uncommitted-changes>
|
||||
</transactions>
|
||||
<session-browser>
|
||||
<disconnect-session value="ASK" />
|
||||
<kill-session value="ASK" />
|
||||
<reload-on-filter-change value="false" />
|
||||
</session-browser>
|
||||
<compiler>
|
||||
<compile-type value="KEEP" />
|
||||
<compile-dependencies value="ASK" />
|
||||
<always-show-controls value="false" />
|
||||
</compiler>
|
||||
<debugger>
|
||||
<debugger-type value="ASK" />
|
||||
<use-generic-runners value="true" />
|
||||
</debugger>
|
||||
</operation-settings>
|
||||
<ddl-file-settings>
|
||||
<extensions>
|
||||
<mapping file-type-id="VIEW" extensions="vw" />
|
||||
<mapping file-type-id="TRIGGER" extensions="trg" />
|
||||
<mapping file-type-id="PROCEDURE" extensions="prc" />
|
||||
<mapping file-type-id="FUNCTION" extensions="fnc" />
|
||||
<mapping file-type-id="PACKAGE" extensions="pkg" />
|
||||
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
|
||||
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
|
||||
<mapping file-type-id="TYPE" extensions="tpe" />
|
||||
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
|
||||
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
|
||||
</extensions>
|
||||
<general>
|
||||
<lookup-ddl-files value="true" />
|
||||
<create-ddl-files value="false" />
|
||||
<synchronize-ddl-files value="true" />
|
||||
<use-qualified-names value="false" />
|
||||
<make-scripts-rerunnable value="true" />
|
||||
</general>
|
||||
</ddl-file-settings>
|
||||
<general-settings>
|
||||
<regional-settings>
|
||||
<date-format value="MEDIUM" />
|
||||
<number-format value="UNGROUPED" />
|
||||
<locale value="SYSTEM_DEFAULT" />
|
||||
<use-custom-formats value="false" />
|
||||
</regional-settings>
|
||||
<environment>
|
||||
<environment-types>
|
||||
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
|
||||
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
|
||||
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
|
||||
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
|
||||
</environment-types>
|
||||
<visibility-settings>
|
||||
<connection-tabs value="true" />
|
||||
<dialog-headers value="true" />
|
||||
<object-editor-tabs value="true" />
|
||||
<script-editor-tabs value="false" />
|
||||
<execution-result-tabs value="true" />
|
||||
</visibility-settings>
|
||||
</environment>
|
||||
</general-settings>
|
||||
</component>
|
||||
<component name="DBNavigator.Project.StatementExecutionManager">
|
||||
<execution-variables />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CargoProjects">
|
||||
<cargoProject FILE="$PROJECT_DIR$/Cargo.toml" />
|
||||
</component>
|
||||
<component name="RustProjectSettings">
|
||||
<option name="toolchainHomeDirectory" value="$USER_HOME$/.cargo/bin" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/no_std_test.iml" filepath="$PROJECT_DIR$/.idea/no_std_test.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/examples" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/benches" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,356 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="a5fba61a-189f-4111-80cb-56c2e159cc7d" name="Default Changelist" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
|
||||
</list>
|
||||
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="FUSProjectUsageTrigger">
|
||||
<session id="421368934">
|
||||
<usages-collector id="statistics.lifecycle.project">
|
||||
<counts>
|
||||
<entry key="project.closed" value="3" />
|
||||
<entry key="project.open.time.10" value="1" />
|
||||
<entry key="project.open.time.11" value="1" />
|
||||
<entry key="project.open.time.2" value="1" />
|
||||
<entry key="project.open.time.21" value="1" />
|
||||
<entry key="project.open.time.8" value="1" />
|
||||
<entry key="project.opened" value="5" />
|
||||
</counts>
|
||||
</usages-collector>
|
||||
<usages-collector id="statistics.file.extensions.open">
|
||||
<counts>
|
||||
<entry key="rs" value="6" />
|
||||
<entry key="toml" value="1" />
|
||||
</counts>
|
||||
</usages-collector>
|
||||
<usages-collector id="statistics.file.types.open">
|
||||
<counts>
|
||||
<entry key="Rust" value="6" />
|
||||
<entry key="TOML" value="1" />
|
||||
</counts>
|
||||
</usages-collector>
|
||||
<usages-collector id="statistics.file.extensions.edit">
|
||||
<counts>
|
||||
<entry key="dummy" value="1" />
|
||||
<entry key="rs" value="21374" />
|
||||
<entry key="toml" value="584" />
|
||||
</counts>
|
||||
</usages-collector>
|
||||
<usages-collector id="statistics.file.types.edit">
|
||||
<counts>
|
||||
<entry key="PLAIN_TEXT" value="1" />
|
||||
<entry key="Rust" value="21374" />
|
||||
<entry key="TOML" value="584" />
|
||||
</counts>
|
||||
</usages-collector>
|
||||
</session>
|
||||
</component>
|
||||
<component name="FileEditorManager">
|
||||
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/lib.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state>
|
||||
<caret column="9" selection-start-column="9" selection-end-column="9" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/main.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="440">
|
||||
<caret line="20" column="6" selection-start-line="20" selection-start-column="6" selection-end-line="20" selection-end-column="6" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/tls_packet.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="3322">
|
||||
<caret line="153" column="27" selection-start-line="153" selection-start-column="27" selection-end-line="153" selection-end-column="27" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/src/tls.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="821">
|
||||
<caret line="409" column="5" selection-start-line="409" selection-start-column="5" selection-end-line="409" selection-end-column="5" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/Cargo.toml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="264">
|
||||
<caret line="12" column="18" selection-start-line="12" selection-start-column="18" selection-end-line="12" selection-end-column="18" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
</leaf>
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="Rust File" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="GradleLocalSettings">
|
||||
<option name="projectSyncType">
|
||||
<map>
|
||||
<entry key="$PROJECT_DIR$/../2019F-COMP3111" value="PREVIEW" />
|
||||
<entry key="$PROJECT_DIR$/../2019F-COMP3111-master" value="PREVIEW" />
|
||||
<entry key="$PROJECT_DIR$/../demo" value="PREVIEW" />
|
||||
<entry key="$PROJECT_DIR$/../project" value="PREVIEW" />
|
||||
<entry key="$PROJECT_DIR$/../projectWithSpringServer" value="PREVIEW" />
|
||||
<entry key="$PROJECT_DIR$/../project_server" value="PREVIEW" />
|
||||
<entry key="$PROJECT_DIR$/../project_testing" value="PREVIEW" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
<component name="IdeDocumentHistory">
|
||||
<option name="CHANGED_PATHS">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/src/main.rs" />
|
||||
<option value="$PROJECT_DIR$/src/lib.rs" />
|
||||
<option value="$PROJECT_DIR$/src/tls_packet.rs" />
|
||||
<option value="$PROJECT_DIR$/Cargo.toml" />
|
||||
<option value="$PROJECT_DIR$/src/tls.rs" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectFrameBounds" extendedState="6">
|
||||
<option name="x" value="539" />
|
||||
<option name="y" value="1068" />
|
||||
<option name="width" value="974" />
|
||||
<option name="height" value="1047" />
|
||||
</component>
|
||||
<component name="ProjectInspectionProfilesVisibleTreeState">
|
||||
<entry key="Project Default">
|
||||
<profile-state>
|
||||
<expanded-state>
|
||||
<State />
|
||||
</expanded-state>
|
||||
<selected-state>
|
||||
<State>
|
||||
<id>Ant</id>
|
||||
</State>
|
||||
</selected-state>
|
||||
</profile-state>
|
||||
</entry>
|
||||
</component>
|
||||
<component name="ProjectView">
|
||||
<navigator proportions="" version="1">
|
||||
<foldersAlwaysOnTop value="true" />
|
||||
</navigator>
|
||||
<panes />
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||
<property name="org.rust.cargo.project.model.PROJECT_DISCOVERY" value="true" />
|
||||
<property name="settings.editor.selected.configurable" value="editor.preferences.fonts.default" />
|
||||
</component>
|
||||
<component name="RunDashboard">
|
||||
<option name="ruleStates">
|
||||
<list>
|
||||
<RuleState>
|
||||
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
|
||||
</RuleState>
|
||||
<RuleState>
|
||||
<option name="name" value="StatusDashboardGroupingRule" />
|
||||
</RuleState>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="RunManager">
|
||||
<configuration name="Run no_std_test" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="command" value="run --package no_std_test --bin no_std_test" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="nocapture" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Cargo Command.Run no_std_test" />
|
||||
</list>
|
||||
</recent_temporary>
|
||||
</component>
|
||||
<component name="SvnConfiguration">
|
||||
<configuration />
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="a5fba61a-189f-4111-80cb-56c2e159cc7d" name="Default Changelist" comment="" />
|
||||
<created>1601521481729</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1601521481729</updated>
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TodoView">
|
||||
<todo-panel id="selected-file">
|
||||
<is-autoscroll-to-source value="true" />
|
||||
</todo-panel>
|
||||
<todo-panel id="all">
|
||||
<are-packages-shown value="true" />
|
||||
<is-autoscroll-to-source value="true" />
|
||||
</todo-panel>
|
||||
</component>
|
||||
<component name="ToolWindowManager">
|
||||
<frame x="-8" y="1072" width="1936" height="1056" extended-state="6" />
|
||||
<editor active="true" />
|
||||
<layout>
|
||||
<window_info content_ui="combo" id="Project" order="0" weight="0.18656716" />
|
||||
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
|
||||
<window_info id="Project Explorer" order="2" />
|
||||
<window_info id="DB Browser" order="3" />
|
||||
<window_info id="Designer" order="4" />
|
||||
<window_info id="UI Designer" order="5" />
|
||||
<window_info id="Job Explorer" order="6" />
|
||||
<window_info id="Favorites" order="7" side_tool="true" />
|
||||
<window_info anchor="bottom" id="Message" order="0" />
|
||||
<window_info anchor="bottom" id="Find" order="1" />
|
||||
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49946696" weight="0.36363637" />
|
||||
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
||||
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||
<window_info anchor="bottom" id="TODO" order="6" weight="0.329718" />
|
||||
<window_info anchor="bottom" id="Console" order="7" />
|
||||
<window_info anchor="bottom" id="DB Execution Console" order="8" />
|
||||
<window_info anchor="bottom" id="Terminal" order="9" weight="0.33296824" />
|
||||
<window_info anchor="bottom" id="Event Log" order="10" sideWeight="0.50053304" side_tool="true" weight="0.329718" />
|
||||
<window_info anchor="bottom" id="Version Control" order="11" />
|
||||
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
|
||||
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
||||
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
||||
<window_info anchor="right" id="Palette" order="3" />
|
||||
<window_info anchor="right" id="Cargo" order="4" />
|
||||
<window_info anchor="right" id="Palette	" order="5" />
|
||||
<window_info anchor="right" id="Maven Projects" order="6" />
|
||||
</layout>
|
||||
<layout-to-restore>
|
||||
<window_info content_ui="combo" id="Project" order="0" weight="0.18656716" />
|
||||
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
|
||||
<window_info id="Project Explorer" order="2" />
|
||||
<window_info id="DB Browser" order="3" />
|
||||
<window_info id="Designer" order="4" />
|
||||
<window_info id="UI Designer" order="5" />
|
||||
<window_info id="Job Explorer" order="6" />
|
||||
<window_info id="Favorites" order="7" side_tool="true" />
|
||||
<window_info anchor="bottom" id="Message" order="0" />
|
||||
<window_info anchor="bottom" id="Find" order="1" />
|
||||
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49946696" weight="0.36442515" />
|
||||
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
|
||||
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||
<window_info anchor="bottom" id="TODO" order="6" weight="0.329718" />
|
||||
<window_info anchor="bottom" id="Console" order="7" />
|
||||
<window_info anchor="bottom" id="DB Execution Console" order="8" />
|
||||
<window_info active="true" anchor="bottom" id="Terminal" order="9" visible="true" weight="0.33296824" />
|
||||
<window_info anchor="bottom" id="Event Log" order="10" sideWeight="0.50053304" side_tool="true" weight="0.329718" />
|
||||
<window_info anchor="bottom" id="Version Control" order="11" />
|
||||
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
|
||||
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
||||
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
||||
<window_info anchor="right" id="Palette" order="3" />
|
||||
<window_info anchor="right" id="Cargo" order="4" />
|
||||
<window_info anchor="right" id="Palette	" order="5" />
|
||||
<window_info anchor="right" id="Maven Projects" order="6" />
|
||||
</layout-to-restore>
|
||||
</component>
|
||||
<component name="VcsContentAnnotationSettings">
|
||||
<option name="myLimit" value="2678400000" />
|
||||
</component>
|
||||
<component name="editorHistoryManager">
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-msvc/lib/rustlib/src/rust/src/libcore/convert/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="245">
|
||||
<caret line="581" column="7" selection-start-line="581" selection-start-column="7" selection-end-line="581" selection-end-column="7" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/lib.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state>
|
||||
<caret column="9" selection-start-column="9" selection-end-column="9" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/main.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="440">
|
||||
<caret line="20" column="6" selection-start-line="20" selection-start-column="6" selection-end-line="20" selection-end-column="6" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/tls_packet.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="3322">
|
||||
<caret line="153" column="27" selection-start-line="153" selection-start-column="27" selection-end-line="153" selection-end-column="27" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/Cargo.toml">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="264">
|
||||
<caret line="12" column="18" selection-start-line="12" selection-start-column="18" selection-end-line="12" selection-end-column="18" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/tls.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="821">
|
||||
<caret line="409" column="5" selection-start-line="409" selection-start-column="5" selection-end-line="409" selection-end-column="5" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</component>
|
||||
<component name="masterDetails">
|
||||
<states>
|
||||
<state key="ProjectJDKs.UI">
|
||||
<settings>
|
||||
<last-edited>10</last-edited>
|
||||
<splitter-proportions>
|
||||
<option name="proportions">
|
||||
<list>
|
||||
<option value="0.2" />
|
||||
</list>
|
||||
</option>
|
||||
</splitter-proportions>
|
||||
</settings>
|
||||
</state>
|
||||
<state key="ScopeChooserConfigurable.UI">
|
||||
<settings>
|
||||
<splitter-proportions>
|
||||
<option name="proportions">
|
||||
<list>
|
||||
<option value="0.2" />
|
||||
</list>
|
||||
</option>
|
||||
</splitter-proportions>
|
||||
</settings>
|
||||
</state>
|
||||
</states>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,442 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "aead"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331"
|
||||
dependencies = [
|
||||
"generic-array 0.14.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aes"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd2bc6d3f370b5666245ff421e231cba4353df936e26986d2918e61a8fd6aef6"
|
||||
dependencies = [
|
||||
"aes-soft",
|
||||
"aesni",
|
||||
"block-cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aes-gcm"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0301c9e9c443494d970a07885e8cf3e587bae8356a1d5abd0999068413f7205f"
|
||||
dependencies = [
|
||||
"aead",
|
||||
"aes",
|
||||
"block-cipher",
|
||||
"ghash",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aes-soft"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63dd91889c49327ad7ef3b500fd1109dbd3c509a03db0d4a9ce413b79f575cb6"
|
||||
dependencies = [
|
||||
"block-cipher",
|
||||
"byteorder",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aesni"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6fe808308bb07d393e2ea47780043ec47683fcf19cf5efc8ca51c50cc8c68a"
|
||||
dependencies = [
|
||||
"block-cipher",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "as-slice"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb4d1c23475b74e3672afa8c2be22040b8b7783ad9b461021144ed10a46bb0e6"
|
||||
dependencies = [
|
||||
"generic-array 0.12.3",
|
||||
"generic-array 0.13.2",
|
||||
"generic-array 0.14.4",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "block-cipher"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f337a3e6da609650eb74e02bc9fac7b735049f7623ab12f2e4c719316fcc7e80"
|
||||
dependencies = [
|
||||
"generic-array 0.14.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "chacha20"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "244fbce0d47e97e8ef2f63b81d5e05882cb518c68531eb33194990d7b7e85845"
|
||||
dependencies = [
|
||||
"stream-cipher",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "chacha20poly1305"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9bf18d374d66df0c05cdddd528a7db98f78c28e2519b120855c4f84c5027b1f5"
|
||||
dependencies = [
|
||||
"aead",
|
||||
"chacha20",
|
||||
"poly1305",
|
||||
"stream-cipher",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ghash"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6e27f0689a6e15944bdce7e45425efb87eaa8ab0c6e87f11d0987a9133e2531"
|
||||
dependencies = [
|
||||
"polyval",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hash32"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heapless"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74911a68a1658cfcfb61bc0ccfbd536e3b6e906f8c2f7883ee50157e3e2184f1"
|
||||
dependencies = [
|
||||
"as-slice",
|
||||
"generic-array 0.13.2",
|
||||
"hash32",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa7087f49d294270db4e1928fc110c976cd4b9e5a16348e0a1df09afa99e6c98"
|
||||
|
||||
[[package]]
|
||||
name = "managed"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c75de51135344a4f8ed3cfe2720dc27736f7711989703a0b43aadf3753c55577"
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "226b45a5c2ac4dd696ed30fa6b94b057ad909c7b7fc2e0d0808192bced894066"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"num_enum_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c0fd9eba1d5db0994a239e09c1be402d35622277e35468ba891aa5e3188ce7e"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "poly1305"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ce46de8e53ee414ca4d02bfefac75d8c12fba948b76622a40b4be34dfce980"
|
||||
dependencies = [
|
||||
"universal-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polyval"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5884790f1ce3553ad55fec37b5aaac5882e0e845a2612df744d6c85c9bf046c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"universal-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
|
||||
dependencies = [
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.116"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5"
|
||||
|
||||
[[package]]
|
||||
name = "smoltcp"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fe46639fd2ec79eadf8fe719f237a7a0bd4dac5d957f1ca5bbdbc1c3c39e53a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"managed",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smoltcp-tls"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"byteorder",
|
||||
"chacha20poly1305",
|
||||
"heapless",
|
||||
"num_enum",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"smoltcp",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "stream-cipher"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c80e15f898d8d8f25db24c253ea615cc14acf418ff307822995814e7d42cfa89"
|
||||
dependencies = [
|
||||
"block-cipher",
|
||||
"generic-array 0.14.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c51d92969d209b54a98397e1b91c8ae82d8c87a7bb87df0b29aa2ad81454228"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "universal-hash"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402"
|
||||
dependencies = [
|
||||
"generic-array 0.14.4",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05f33972566adbd2d3588b0491eb94b98b43695c4ef897903470ede4f3f5a28a"
|
|
@ -0,0 +1,33 @@
|
|||
[package]
|
||||
name = "smoltcp-tls"
|
||||
version = "0.1.0"
|
||||
authors = ["occheung <occheung@connect.ust.hk>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
aes-gcm = "0.7.0"
|
||||
chacha20poly1305 = "0.6.0"
|
||||
byteorder = "1.3.4"
|
||||
num_enum = "0.5.1"
|
||||
|
||||
[dependencies.smoltcp]
|
||||
version = "0.6.0"
|
||||
default-features = false
|
||||
features = ["proto-ipv4", "proto-ipv6", "socket-tcp"]
|
||||
|
||||
[dependencies.rand_chacha]
|
||||
version = "0.2.2"
|
||||
default-features = false
|
||||
features = []
|
||||
|
||||
[dependencies.rand]
|
||||
version = "0.7.3"
|
||||
default-features = false
|
||||
features = ["getrandom"]
|
||||
|
||||
[dependencies.heapless]
|
||||
version = "0.5.6"
|
||||
default-features = false
|
||||
features = []
|
|
@ -0,0 +1,4 @@
|
|||
#![no_std]
|
||||
|
||||
pub mod tls;
|
||||
pub mod tls_packet;
|
|
@ -0,0 +1,30 @@
|
|||
use smoltcp_tls::tls::TlsSocket;
|
||||
use smoltcp::socket::TcpSocketBuffer;
|
||||
use smoltcp::socket::SocketSet;
|
||||
use smoltcp::wire::Ipv4Address;
|
||||
|
||||
fn main() {
|
||||
let mut socket_set_entries: [_; 8] = Default::default();
|
||||
let mut sockets = SocketSet::new(&mut socket_set_entries[..]);
|
||||
|
||||
let mut tx_storage = [0; 4096];
|
||||
let mut rx_storage = [0; 4096];
|
||||
|
||||
let mut tls_socket = {
|
||||
let tx_buffer = TcpSocketBuffer::new(&mut tx_storage[..]);
|
||||
let rx_buffer = TcpSocketBuffer::new(&mut rx_storage[..]);
|
||||
TlsSocket::new(
|
||||
&mut sockets,
|
||||
rx_buffer,
|
||||
tx_buffer
|
||||
)
|
||||
};
|
||||
|
||||
tls_socket.tcp_connect(
|
||||
&mut sockets,
|
||||
(Ipv4Address::new(192, 168, 1, 125), 1883),
|
||||
49600
|
||||
).unwrap();
|
||||
|
||||
tls_socket.tls_connect(&mut sockets).unwrap();
|
||||
}
|
|
@ -0,0 +1,449 @@
|
|||
use smoltcp::socket::TcpSocket;
|
||||
use smoltcp::socket::TcpState;
|
||||
use smoltcp::socket::Socket;
|
||||
use smoltcp::socket::AnySocket;
|
||||
use smoltcp::socket::SocketRef;
|
||||
use smoltcp::socket::SocketHandle;
|
||||
use smoltcp::socket::SocketSet;
|
||||
use smoltcp::socket::TcpSocketBuffer;
|
||||
use smoltcp::wire::Ipv4Address;
|
||||
use smoltcp::wire::IpEndpoint;
|
||||
use smoltcp::Result;
|
||||
use smoltcp::Error;
|
||||
|
||||
use byteorder::{ByteOrder, NetworkEndian, BigEndian, WriteBytesExt};
|
||||
|
||||
use rand::prelude::*;
|
||||
use rand_chacha::ChaCha20Rng;
|
||||
|
||||
use heapless::Vec;
|
||||
use heapless::consts::*;
|
||||
|
||||
use core::convert::TryInto;
|
||||
use core::convert::TryFrom;
|
||||
|
||||
use crate::tls_packet::*;
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
#[allow(non_camel_case_types)]
|
||||
enum TlsState {
|
||||
START,
|
||||
WAIT_SH,
|
||||
WAIT_EE,
|
||||
WAIT_CERT_CR,
|
||||
WAIT_CERT,
|
||||
WAIT_CV,
|
||||
WAIT_FINISHED,
|
||||
CONNECTED,
|
||||
}
|
||||
|
||||
pub struct TlsSocket
|
||||
{
|
||||
state: TlsState,
|
||||
tcp_handle: SocketHandle,
|
||||
random: ChaCha20Rng,
|
||||
}
|
||||
|
||||
impl TlsSocket {
|
||||
pub fn new<'a, 'b, 'c>(
|
||||
sockets: &mut SocketSet<'a, 'b, 'c>,
|
||||
rx_buffer: TcpSocketBuffer<'b>,
|
||||
tx_buffer: TcpSocketBuffer<'b>,
|
||||
) -> Self
|
||||
where
|
||||
'b: 'c,
|
||||
{
|
||||
let tcp_socket = TcpSocket::new(rx_buffer, tx_buffer);
|
||||
let tcp_handle = sockets.add(tcp_socket);
|
||||
TlsSocket {
|
||||
state: TlsState::START,
|
||||
tcp_handle,
|
||||
random: ChaCha20Rng::from_entropy(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tcp_connect<T, U>(
|
||||
&mut self,
|
||||
sockets: &mut SocketSet,
|
||||
remote_endpoint: T,
|
||||
local_endpoint: U,
|
||||
) -> Result<()>
|
||||
where
|
||||
T: Into<IpEndpoint>,
|
||||
U: Into<IpEndpoint>,
|
||||
{
|
||||
let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle);
|
||||
tcp_socket.connect(remote_endpoint, local_endpoint)
|
||||
}
|
||||
|
||||
pub fn tls_connect(&mut self, sockets: &mut SocketSet) -> Result<bool> {
|
||||
// Check tcp_socket connectivity
|
||||
{
|
||||
let tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle);
|
||||
if tcp_socket.state() != TcpState::Established {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
|
||||
if self.state == TlsState::START {
|
||||
// Create TLS representation, length and payload not finalised
|
||||
let mut random: [u8; 32] = [0; 32];
|
||||
let mut session_id: [u8; 32] = [0; 32];
|
||||
self.random.fill_bytes(&mut random);
|
||||
self.random.fill_bytes(&mut session_id);
|
||||
|
||||
let cipher_suites_length = 3;
|
||||
let cipher_suites = [
|
||||
CipherSuite::TLS_AES_128_GCM_SHA256,
|
||||
CipherSuite::TLS_AES_256_GCM_SHA384,
|
||||
CipherSuite::TLS_CHACHA20_POLY1305_SHA256,
|
||||
];
|
||||
|
||||
// Length: to be determined
|
||||
let supported_versions_extension = Extension {
|
||||
extension_type: ExtensionType::SupportedVersions,
|
||||
length: 3,
|
||||
extension_data: &[
|
||||
2, // Number of supported versions * 2
|
||||
// Need 2 bytes to contain a version
|
||||
0x03, 0x04 // 0x0303: TLS Version 1.3
|
||||
]
|
||||
};
|
||||
|
||||
let client_hello = ClientHello {
|
||||
version: TlsVersion::Tls12,
|
||||
random,
|
||||
session_id_length: 32,
|
||||
session_id,
|
||||
cipher_suites_length,
|
||||
cipher_suites: &cipher_suites,
|
||||
compression_method_length: 1,
|
||||
compression_methods: 0,
|
||||
extension_length: supported_versions_extension.get_length(),
|
||||
extensions: &[supported_versions_extension],
|
||||
};
|
||||
|
||||
let handshake_repr = HandshakeRepr {
|
||||
msg_type: HandshakeType::ClientHello,
|
||||
length: client_hello.get_length(),
|
||||
handshake_data: HandshakeData::ClientHello(client_hello),
|
||||
};
|
||||
|
||||
let repr = TlsRepr {
|
||||
content_type: TlsContentType::Handshake,
|
||||
version: TlsVersion::Tls13,
|
||||
length: 0,
|
||||
payload: None,
|
||||
handshake: Some(handshake_repr),
|
||||
};
|
||||
|
||||
self.send_tls_repr(sockets, repr)?;
|
||||
self.state = TlsState::WAIT_SH;
|
||||
Ok(true)
|
||||
} else if self.state == TlsState::WAIT_SH {
|
||||
Ok(true)
|
||||
} else {
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
|
||||
// Generic inner send method, through TCP socket
|
||||
fn send_tls_repr(&mut self, sockets: &mut SocketSet, tls_repr: TlsRepr) -> Result<()> {
|
||||
let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle);
|
||||
let mut array = [0; 2048];
|
||||
let mut buffer = TlsBuffer::new(&mut array);
|
||||
buffer.enqueue_tls_repr(tls_repr)?;
|
||||
let buffer_size = buffer.index.clone();
|
||||
tcp_socket.send_slice(buffer.into())
|
||||
.and_then(
|
||||
|size| if size == buffer_size.into_inner() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::Truncated)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// Generic inner recv method, through TCP socket
|
||||
fn recv_tls_repr<'a>(&'a mut self, sockets: &mut SocketSet, byte_array: &'a mut [u8]) -> Result<TlsRepr<'a, '_>> {
|
||||
let mut tcp_socket = sockets.get::<TcpSocket>(self.tcp_handle);
|
||||
let size = tcp_socket.recv_slice(byte_array)?;
|
||||
let buffer = TlsBuffer::new(&mut byte_array[..size]);
|
||||
buffer.dequeue_tls_repr()
|
||||
}
|
||||
}
|
||||
|
||||
// Only designed to support read or write the entire buffer
|
||||
pub(crate) struct TlsBuffer<'a> {
|
||||
buffer: &'a mut [u8],
|
||||
index: core::cell::RefCell<usize>,
|
||||
}
|
||||
|
||||
impl<'a> Into<&'a [u8]> for TlsBuffer<'a> {
|
||||
fn into(self) -> &'a [u8] {
|
||||
&self.buffer[0..self.index.into_inner()]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TlsBuffer<'a> {
|
||||
pub(crate) fn new(buffer: &'a mut [u8]) -> Self {
|
||||
Self {
|
||||
buffer,
|
||||
index: core::cell::RefCell::new(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn write(&mut self, data: &[u8]) -> Result<()> {
|
||||
let mut index = self.index.borrow_mut();
|
||||
if (self.buffer.len() - *index) < data.len() {
|
||||
return Err(Error::Exhausted);
|
||||
}
|
||||
let next_index = *index + data.len();
|
||||
self.buffer[*index..next_index].copy_from_slice(data);
|
||||
*index = next_index;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn write_u8(&mut self, data: u8) -> Result<()> {
|
||||
let mut index = self.index.borrow_mut();
|
||||
if (self.buffer.len() - *index) < 1 {
|
||||
return Err(Error::Exhausted);
|
||||
}
|
||||
self.buffer[*index] = data;
|
||||
*index += 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn read_u8(&mut self) -> Result<u8> {
|
||||
let mut index = self.index.borrow_mut();
|
||||
if (self.buffer.len() - *index) < 1 {
|
||||
return Err(Error::Exhausted);
|
||||
}
|
||||
let data = self.buffer[*index];
|
||||
*index += 1;
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
pub(crate) fn read_all(self) -> &'a [u8] {
|
||||
&self.buffer[self.index.into_inner()..]
|
||||
}
|
||||
|
||||
pub(crate) fn read_slice(&self, length: usize) -> Result<&[u8]> {
|
||||
let mut index = self.index.borrow_mut();
|
||||
if (self.buffer.len() - *index) < length {
|
||||
return Err(Error::Exhausted);
|
||||
}
|
||||
let next_index = *index + length;
|
||||
let slice = &self.buffer[*index..next_index];
|
||||
*index = next_index;
|
||||
Ok(slice)
|
||||
}
|
||||
|
||||
fn enqueue_tls_repr(&mut self, tls_repr: TlsRepr) -> Result<()> {
|
||||
self.write_u8(tls_repr.content_type.into())?;
|
||||
self.write_u16(tls_repr.version.into())?;
|
||||
self.write_u16(tls_repr.length)?;
|
||||
if let Some(app_data) = tls_repr.payload {
|
||||
self.write(app_data)?;
|
||||
} else if let Some(handshake_repr) = tls_repr.handshake {
|
||||
// Queue handshake_repr into buffer
|
||||
self.enqueue_handshake_repr(handshake_repr)?;
|
||||
} else {
|
||||
return Err(Error::Malformed);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn enqueue_handshake_repr(&mut self, handshake_repr: HandshakeRepr) -> Result<()> {
|
||||
self.write_u8(handshake_repr.msg_type.into())?;
|
||||
self.write_u24(handshake_repr.length)?;
|
||||
self.enqueue_handshake_data(handshake_repr.handshake_data)
|
||||
}
|
||||
|
||||
fn enqueue_handshake_data(&mut self, handshake_data: HandshakeData) -> Result<()> {
|
||||
match handshake_data {
|
||||
HandshakeData::ClientHello(client_hello) => {
|
||||
self.enqueue_client_hello(client_hello)
|
||||
}
|
||||
_ => {
|
||||
Err(Error::Unrecognized)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn enqueue_client_hello(&mut self, client_hello: ClientHello) -> Result<()> {
|
||||
self.write_u16(client_hello.version.into())?;
|
||||
self.write(&client_hello.random)?;
|
||||
self.write_u8(client_hello.session_id_length)?;
|
||||
self.write(&client_hello.session_id)?;
|
||||
self.write_u16(client_hello.cipher_suites_length)?;
|
||||
for suite in client_hello.cipher_suites.iter() {
|
||||
self.write_u16((*suite).into())?;
|
||||
}
|
||||
self.write_u8(client_hello.compression_method_length)?;
|
||||
self.write_u8(client_hello.compression_methods)?;
|
||||
self.write_u16(client_hello.extension_length)?;
|
||||
self.enqueue_extensions(client_hello.extensions)
|
||||
}
|
||||
|
||||
fn enqueue_extensions(&mut self, extensions: &[Extension]) -> Result<()> {
|
||||
for extension in extensions {
|
||||
self.write_u16(extension.extension_type.into())?;
|
||||
self.write_u16(extension.length)?;
|
||||
self.write(extension.extension_data)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn dequeue_tls_repr<'b>(mut self) -> Result<TlsRepr<'a, 'b>> {
|
||||
// Create a TLS Representation layer
|
||||
// Modify the representation along the way
|
||||
let mut repr = TlsRepr {
|
||||
content_type: TlsContentType::Invalid,
|
||||
version: TlsVersion::Tls10,
|
||||
length: 0,
|
||||
payload: None,
|
||||
handshake: None,
|
||||
};
|
||||
|
||||
repr.content_type = TlsContentType::try_from(self.read_u8()?)
|
||||
.map_err(|_| Error::Unrecognized)?;
|
||||
repr.version = TlsVersion::try_from(self.read_u16()?)
|
||||
.map_err(|_| Error::Unrecognized)?;
|
||||
repr.length = self.read_u16()?;
|
||||
|
||||
use TlsContentType::*;
|
||||
match repr.content_type {
|
||||
Invalid => Err(Error::Unrecognized),
|
||||
ChangeCipherSpec | Alert => unimplemented!(),
|
||||
Handshake => todo!(),
|
||||
ApplicationData => {
|
||||
repr.payload = Some(self.read_all());
|
||||
Ok(repr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn dequeue_handshake<'b>(mut self) -> Result<HandshakeRepr<'a, 'b>> {
|
||||
// Create a Handshake header representation
|
||||
// Fill in proper value afterwards
|
||||
let mut repr = HandshakeRepr {
|
||||
msg_type: HandshakeType::ClientHello,
|
||||
length: 0,
|
||||
handshake_data: HandshakeData::Uninitialized,
|
||||
};
|
||||
|
||||
repr.msg_type = HandshakeType::try_from(self.read_u8()?)
|
||||
.map_err(|_| Error::Unrecognized)?;
|
||||
repr.length = self.read_u24()?;
|
||||
|
||||
use HandshakeType::*;
|
||||
match repr.msg_type {
|
||||
ClientHello => unimplemented!(),
|
||||
ServerHello => todo!(),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn dequeue_server_hello(mut self) -> Result<ServerHello<'static, 'static>> {
|
||||
// Create a Server Hello representation
|
||||
// Fill in proper value afterwards
|
||||
let mut server_hello = ServerHello {
|
||||
version: TlsVersion::Tls10,
|
||||
random: [0; 32],
|
||||
session_id_echo_length: 0,
|
||||
session_id_echo: [0; 32],
|
||||
cipher_suite: CipherSuite::TLS_CHACHA20_POLY1305_SHA256,
|
||||
compression_method: 0,
|
||||
extension_length: 0,
|
||||
extensions: &[],
|
||||
};
|
||||
|
||||
server_hello.version = TlsVersion::try_from(self.read_u16()?)
|
||||
.map_err(|_| Error::Unrecognized)?;
|
||||
for random_byte in &mut server_hello.random[..] {
|
||||
*random_byte = self.read_u8()?;
|
||||
}
|
||||
server_hello.session_id_echo_length = self.read_u8()?;
|
||||
for id_byte in &mut server_hello.session_id_echo[
|
||||
..usize::try_from(server_hello.session_id_echo_length)
|
||||
.map_err(|_| Error::Exhausted)?
|
||||
] {
|
||||
*id_byte = self.read_u8()?;
|
||||
}
|
||||
server_hello.cipher_suite = CipherSuite::try_from(self.read_u16()?)
|
||||
.map_err(|_| Error::Unrecognized)?;
|
||||
server_hello.compression_method = self.read_u8()?;
|
||||
server_hello.extension_length = self.read_u16()?;
|
||||
|
||||
let mut remaining_length = server_hello.extension_length;
|
||||
let mut extension_counter = 0;
|
||||
let mut extension_vec: Vec<Extension, U32> = Vec::new();
|
||||
while remaining_length != 0 {
|
||||
extension_vec.push(self.dequeue_extension()?.clone())
|
||||
.map_err(|_| Error::Exhausted)?;
|
||||
// Deduct base length of an extension (ext_type, len)
|
||||
remaining_length -= 4;
|
||||
remaining_length -= extension_vec[extension_counter].length;
|
||||
extension_counter += 1;
|
||||
}
|
||||
|
||||
Ok(server_hello)
|
||||
}
|
||||
|
||||
fn dequeue_extension(&self) -> Result<Extension<'_>> {
|
||||
// Create an Extension representation
|
||||
// Fill in proper value afterwards
|
||||
let mut extension = Extension {
|
||||
extension_type: ExtensionType::ServerName,
|
||||
length: 0,
|
||||
extension_data: &[],
|
||||
};
|
||||
|
||||
extension.extension_type = ExtensionType::try_from(self.read_u16()?)
|
||||
.map_err(|_| Error::Unrecognized)?;
|
||||
extension.length = self.read_u16()?;
|
||||
extension.extension_data = self.read_slice(
|
||||
usize::try_from(extension.length)
|
||||
.map_err(|_| Error::Exhausted)?
|
||||
)?;
|
||||
Ok(extension)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! export_byte_order_fn {
|
||||
($($write_fn_name: ident, $read_fn_name: ident, $data_type: ty, $data_size: literal),+) => {
|
||||
impl<'a> TlsBuffer<'a> {
|
||||
$(
|
||||
pub(crate) fn $write_fn_name(&mut self, data: $data_type) -> Result<()> {
|
||||
let mut index = self.index.borrow_mut();
|
||||
if (self.buffer.len() - *index) < $data_size {
|
||||
return Err(Error::Exhausted);
|
||||
}
|
||||
let next_index = *index + $data_size;
|
||||
NetworkEndian::$write_fn_name(&mut self.buffer[*index..next_index], data);
|
||||
*index = next_index;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn $read_fn_name(&self) -> Result<$data_type> {
|
||||
let mut index = self.index.borrow_mut();
|
||||
if (self.buffer.len() - *index) < $data_size {
|
||||
return Err(Error::Exhausted);
|
||||
}
|
||||
let next_index = *index + $data_size;
|
||||
let data = NetworkEndian::$read_fn_name(&self.buffer[*index..next_index]);
|
||||
*index = next_index;
|
||||
Ok(data)
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export_byte_order_fn!(
|
||||
write_u16, read_u16, u16, 2,
|
||||
write_u24, read_u24, u32, 3,
|
||||
write_u32, read_u32, u32, 4,
|
||||
write_u48, read_u48, u64, 6,
|
||||
write_u64, read_u64, u64, 8
|
||||
);
|
|
@ -0,0 +1,162 @@
|
|||
use byteorder::{ByteOrder, NetworkEndian, BigEndian};
|
||||
use num_enum::IntoPrimitive;
|
||||
use num_enum::TryFromPrimitive;
|
||||
use core::convert::TryFrom;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
|
||||
#[repr(u8)]
|
||||
pub(crate) enum TlsContentType {
|
||||
Invalid = 0,
|
||||
ChangeCipherSpec = 20,
|
||||
Alert = 21,
|
||||
Handshake = 22,
|
||||
ApplicationData = 23
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
|
||||
#[repr(u16)]
|
||||
pub(crate) enum TlsVersion {
|
||||
Tls10 = 0x0301,
|
||||
Tls11 = 0x0302,
|
||||
Tls12 = 0x0303,
|
||||
Tls13 = 0x0304,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) struct TlsRepr<'a, 'b> {
|
||||
pub(crate) content_type: TlsContentType,
|
||||
pub(crate) version: TlsVersion,
|
||||
pub(crate) length: u16,
|
||||
pub(crate) payload: Option<&'a[u8]>,
|
||||
pub(crate) handshake: Option<HandshakeRepr<'a, 'b>>
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
|
||||
#[repr(u8)]
|
||||
pub(crate) enum HandshakeType {
|
||||
ClientHello = 1,
|
||||
ServerHello = 2,
|
||||
NewSessionTicket = 4,
|
||||
EndOfEarlyData = 5,
|
||||
EncryptedExtensions = 8,
|
||||
Certificate = 11,
|
||||
CertificateRequest = 13,
|
||||
CertificateVerify = 15,
|
||||
Finished = 20,
|
||||
KeyUpdate = 24,
|
||||
MessageHash = 254,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) struct HandshakeRepr<'a, 'b> {
|
||||
pub(crate) msg_type: HandshakeType,
|
||||
pub(crate) length: u32,
|
||||
pub(crate) handshake_data: HandshakeData<'a, 'b>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
|
||||
#[repr(u16)]
|
||||
pub(crate) enum CipherSuite {
|
||||
TLS_AES_128_GCM_SHA256 = 0x1301,
|
||||
TLS_AES_256_GCM_SHA384 = 0x1302,
|
||||
TLS_CHACHA20_POLY1305_SHA256 = 0x1303,
|
||||
TLS_AES_128_CCM_SHA256 = 0x1304,
|
||||
TLS_AES_128_CCM_8_SHA256 = 0x1305,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) struct ClientHello<'a, 'b> {
|
||||
pub(crate) version: TlsVersion, // Legacy: Must be Tls12 (0x0303)
|
||||
pub(crate) random: [u8; 32],
|
||||
pub(crate) session_id_length: u8, // Legacy: Keep it 32
|
||||
pub(crate) session_id: [u8; 32], // Legacy: Fill this with an unpredictable value
|
||||
pub(crate) cipher_suites_length: u16,
|
||||
pub(crate) cipher_suites: &'a[CipherSuite],
|
||||
pub(crate) compression_method_length: u8, // Legacy: Must be 1, to contain a byte
|
||||
pub(crate) compression_methods: u8, // Legacy: Must be 1 byte of 0
|
||||
pub(crate) extension_length: u16,
|
||||
pub(crate) extensions: &'a[Extension<'b>],
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) enum HandshakeData<'a, 'b> {
|
||||
Uninitialized,
|
||||
ClientHello(ClientHello<'a, 'b>),
|
||||
ServerHello(ServerHello<'a, 'b>),
|
||||
}
|
||||
|
||||
impl<'a, 'b> ClientHello<'a, 'b> {
|
||||
pub(crate) fn get_length(&self) -> u32 {
|
||||
let mut length :u32 = 2; // TlsVersion size
|
||||
length += 32; // Random size
|
||||
length += 1; // Legacy session_id length size
|
||||
length += 32; // Legacy session_id size
|
||||
length += 2; // Cipher_suites_length size
|
||||
length += (self.cipher_suites.len() as u32) * 2;
|
||||
length += 1;
|
||||
length += 1;
|
||||
length += 2;
|
||||
for extension in self.extensions.iter() {
|
||||
length += (extension.get_length() as u32);
|
||||
}
|
||||
length
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) struct ServerHello<'a, 'b> {
|
||||
pub(crate) version: TlsVersion,
|
||||
pub(crate) random: [u8; 32],
|
||||
pub(crate) session_id_echo_length: u8,
|
||||
pub(crate) session_id_echo: [u8; 32],
|
||||
pub(crate) cipher_suite: CipherSuite,
|
||||
pub(crate) compression_method: u8, // Always 0
|
||||
pub(crate) extension_length: u16,
|
||||
pub(crate) extensions: &'a[Extension<'b>],
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, IntoPrimitive, TryFromPrimitive)]
|
||||
#[repr(u16)]
|
||||
pub(crate) enum ExtensionType {
|
||||
ServerName = 0,
|
||||
MaxFragmentLength = 1,
|
||||
StatusRequest = 5,
|
||||
SupportedGroups = 10,
|
||||
SignatureAlgorithms = 13,
|
||||
UseSRTP = 14,
|
||||
Heartbeat = 15,
|
||||
ApplicationLayerProtocolNegotiation = 16,
|
||||
SignedCertificateTimestamp = 18,
|
||||
ClientCertificateType = 19,
|
||||
ServerCertificateType = 20,
|
||||
Padding = 21,
|
||||
PreSharedKey = 41,
|
||||
EarlyData = 42,
|
||||
SupportedVersions = 43,
|
||||
Cookie = 44,
|
||||
PSKKeyExchangeModes = 45,
|
||||
CertificateAuthorities = 47,
|
||||
OIDFilters = 48,
|
||||
PostHandshakeAuth = 49,
|
||||
SignatureAlgorithmsCert = 50,
|
||||
KeyShare = 51,
|
||||
}
|
||||
|
||||
impl ExtensionType {
|
||||
pub(crate) fn get_length(&self) -> u16 {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) struct Extension<'a> {
|
||||
pub(crate) extension_type: ExtensionType,
|
||||
pub(crate) length: u16,
|
||||
pub(crate) extension_data: &'a[u8],
|
||||
}
|
||||
|
||||
impl<'a> Extension<'a> {
|
||||
pub(crate) fn get_length(&self) -> u16 {
|
||||
self.extension_type.get_length() + 2 + (self.extension_data.len() as u16)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue