{"action":"created","comment":{"url":"https://api.github.com/repos/OISF/suricata/pulls/comments/166746148","pull_request_review_id":94832648,"id":166746148,"diff_hunk":"@@ -0,0 +1,290 @@\n+/* Copyright (C) 2007-2017 Open Information Security Foundation\n+ *\n+ * You can copy, redistribute or modify this Program under the terms of\n+ * the GNU General Public License version 2 as published by the Free\n+ * Software Foundation.\n+ *\n+ * This program is distributed in the hope that it will be useful,\n+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+ * GNU General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU General Public License\n+ * version 2 along with this program; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n+ * 02110-1301, USA.\n+ */\n+\n+/**\n+ * \\file\n+ *\n+ * \\author Mats Klepsland <mats.klepsland@gmail.com>\n+ *\n+ * Functions used to generate JA3 fingerprint.\n+ */\n+\n+#include \"suricata-common.h\"\n+\n+#include \"util-ja3.h\"\n+\n+#define MD5_STRING_LENGTH 33\n+\n+/**\n+ * \\brief Allocate new buffer.\n+ *\n+ * \\return pointer to buffer on success.\n+ * \\return NULL on failure.\n+ */\n+JA3Buffer *Ja3BufferInit(void)\n+{\n+    JA3Buffer *buffer = SCCalloc(1, sizeof(JA3Buffer));\n+    if (buffer == NULL) {\n+        SCLogError(SC_ERR_MEM_ALLOC, \"Error allocating memory for JA3 buffer\");\n+        return NULL;\n+    }\n+\n+    return buffer;\n+}\n+\n+/**\n+ * \\brief Free allocated buffer.\n+ *\n+ * \\param buffer The buffer to free.\n+ */\n+void Ja3BufferFree(JA3Buffer *buffer)\n+{\n+    if (buffer == NULL) {\n+        SCLogError(SC_ERR_INVALID_ARGUMENT, \"Buffer should not be NULL\");\n+        return;\n+    }\n+\n+    if (buffer->data != NULL) {\n+        SCFree(buffer->data);\n+    }\n+\n+    SCFree(buffer);\n+}\n+\n+/**\n+ * \\internal\n+ * \\brief Resize buffer if it is full.\n+ *\n+ * \\param buffer The buffer.\n+ * \\param len    The length of the data that should fit into the buffer.\n+ *\n+ * \\retval 0 on success.\n+ * \\retval -1 on failure.\n+ */\n+static int Ja3BufferResizeIfFull(JA3Buffer *buffer, uint32_t len)\n+{\n+    if (buffer == NULL) {\n+        SCLogError(SC_ERR_INVALID_ARGUMENT, \"Buffer should not be empty\");","path":"src/util-ja3.c","position":81,"original_position":81,"commit_id":"11c3aa05ebd7b9b15a194eb1c0791375f97dcda7","original_commit_id":"11c3aa05ebd7b9b15a194eb1c0791375f97dcda7","user":{"login":"victorjulien","id":32410611,"avatar_url":"https://avatars3.githubusercontent.com/u/32410611?v=4","gravatar_id":"","url":"https://api.github.com/users/victorjulien","html_url":"https://github.com/victorjulien","followers_url":"https://api.github.com/users/victorjulien/followers","following_url":"https://api.github.com/users/victorjulien/following{/other_user}","gists_url":"https://api.github.com/users/victorjulien/gists{/gist_id}","starred_url":"https://api.github.com/users/victorjulien/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/victorjulien/subscriptions","organizations_url":"https://api.github.com/users/victorjulien/orgs","repos_url":"https://api.github.com/users/victorjulien/repos","events_url":"https://api.github.com/users/victorjulien/events{/privacy}","received_events_url":"https://api.github.com/users/victorjulien/received_events","type":"User","site_admin":false},"body":"same here","created_at":"2018-02-07T20:32:05Z","updated_at":"2018-02-07T20:42:46Z","html_url":"https://github.com/OISF/suricata/pull/3215#discussion_r166746148","pull_request_url":"https://api.github.com/repos/OISF/suricata/pulls/3215","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/OISF/suricata/pulls/comments/166746148"},"html":{"href":"https://github.com/OISF/suricata/pull/3215#discussion_r166746148"},"pull_request":{"href":"https://api.github.com/repos/OISF/suricata/pulls/3215"}}},"pull_request":{"url":"https://api.github.com/repos/OISF/suricata/pulls/3215","id":167104149,"html_url":"https://github.com/OISF/suricata/pull/3215","diff_url":"https://github.com/OISF/suricata/pull/3215.diff","patch_url":"https://github.com/OISF/suricata/pull/3215.patch","issue_url":"https://api.github.com/repos/OISF/suricata/issues/3215","number":3215,"state":"open","locked":false,"title":"Initial JA3 integration","user":{"login":"thus","id":75630,"avatar_url":"https://avatars3.githubusercontent.com/u/75630?v=4","gravatar_id":"","url":"https://api.github.com/users/thus","html_url":"https://github.com/thus","followers_url":"https://api.github.com/users/thus/followers","following_url":"https://api.github.com/users/thus/following{/other_user}","gists_url":"https://api.github.com/users/thus/gists{/gist_id}","starred_url":"https://api.github.com/users/thus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thus/subscriptions","organizations_url":"https://api.github.com/users/thus/orgs","repos_url":"https://api.github.com/users/thus/repos","events_url":"https://api.github.com/users/thus/events{/privacy}","received_events_url":"https://api.github.com/users/thus/received_events","type":"User","site_admin":false},"body":"This PR contains an initial JA3 integration (https://github.com/salesforce/ja3). This means that there are some features that are not done yet, and that will (hopefully) be added in the future, but it contains the core functionality.\r\n\r\nFeatures implemented:\r\n* Decode more of the TLS CLIENT_HELLO packet, and generate a JA3 string and a JA3 hash (md5sum of the JA3 string).\r\n* Detection (mpm) keyword 'ja3_hash' for matching on the JA3 hash.\r\n* Detection (mpm) keyword 'ja3_str' for matching on the entire or parts of the JA3 string.\r\n* JSON logger for JA3.\r\n* JA3 metadata in alerts.\r\n* Lua functions 'Ja3GetHash' and 'Ja3GetStr' to access the JA3 buffers from Lua scripts.\r\n* 'ja3_hash' and 'ja3_str' as custom fields in the TLS JSON logger.\r\n\r\nAs I briefly discussed with @inliniac, I also want to implement 'ja3_desc'. To do this I want to read a JSON file with JA3 fingerprints (hash, string and description) when Suricata starts and on rule reload. This file should contain all the known fingerprints and enable us to match on part of the description, e.g. \"ja3_desc; content:\"Firefox\";). It should also enable us to match on all unknown JA3 fingerprints. Since the de_ctx is not available when decoding the TLS packet, I have not added this feature yet, but it is something that (IMO) would add a lot of value to the JA3 integration.\r\n\r\nAs of now, I have choose to disable generating JA3 fingerprints by default. I have added an entry to enable it to the suricata.yaml file in the repo, but this means that it won't be enabled before the user updates their Suricata config. Please let me know if you disagree on doing this.\r\n\r\nRedmine:\r\nhttps://redmine.openinfosecfoundation.org/issues/2192\r\n\r\nPrscript:\r\n- PR thus-pcap: https://buildbot.openinfosecfoundation.org/builders/thus-pcap/builds/144\r\n- PR thus: https://buildbot.openinfosecfoundation.org/builders/thus/builds/144","created_at":"2018-02-05T10:16:49Z","updated_at":"2018-02-07T20:42:46Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c493b0544424b4a5899933c1d6241d620f9e9d58","assignee":null,"assignees":[],"requested_reviewers":[{"login":"norg","id":250673,"avatar_url":"https://avatars3.githubusercontent.com/u/250673?v=4","gravatar_id":"","url":"https://api.github.com/users/norg","html_url":"https://github.com/norg","followers_url":"https://api.github.com/users/norg/followers","following_url":"https://api.github.com/users/norg/following{/other_user}","gists_url":"https://api.github.com/users/norg/gists{/gist_id}","starred_url":"https://api.github.com/users/norg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/norg/subscriptions","organizations_url":"https://api.github.com/users/norg/orgs","repos_url":"https://api.github.com/users/norg/repos","events_url":"https://api.github.com/users/norg/events{/privacy}","received_events_url":"https://api.github.com/users/norg/received_events","type":"User","site_admin":false}],"requested_teams":[],"milestone":null,"commits_url":"https://api.github.com/repos/OISF/suricata/pulls/3215/commits","review_comments_url":"https://api.github.com/repos/OISF/suricata/pulls/3215/comments","review_comment_url":"https://api.github.com/repos/OISF/suricata/pulls/comments{/number}","comments_url":"https://api.github.com/repos/OISF/suricata/issues/3215/comments","statuses_url":"https://api.github.com/repos/OISF/suricata/statuses/11c3aa05ebd7b9b15a194eb1c0791375f97dcda7","head":{"label":"thus:dev-tls-ja3-v12","ref":"dev-tls-ja3-v12","sha":"11c3aa05ebd7b9b15a194eb1c0791375f97dcda7","user":{"login":"thus","id":75630,"avatar_url":"https://avatars3.githubusercontent.com/u/75630?v=4","gravatar_id":"","url":"https://api.github.com/users/thus","html_url":"https://github.com/thus","followers_url":"https://api.github.com/users/thus/followers","following_url":"https://api.github.com/users/thus/following{/other_user}","gists_url":"https://api.github.com/users/thus/gists{/gist_id}","starred_url":"https://api.github.com/users/thus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thus/subscriptions","organizations_url":"https://api.github.com/users/thus/orgs","repos_url":"https://api.github.com/users/thus/repos","events_url":"https://api.github.com/users/thus/events{/privacy}","received_events_url":"https://api.github.com/users/thus/received_events","type":"User","site_admin":false},"repo":{"id":43420959,"name":"suricata","full_name":"thus/suricata","owner":{"login":"thus","id":75630,"avatar_url":"https://avatars3.githubusercontent.com/u/75630?v=4","gravatar_id":"","url":"https://api.github.com/users/thus","html_url":"https://github.com/thus","followers_url":"https://api.github.com/users/thus/followers","following_url":"https://api.github.com/users/thus/following{/other_user}","gists_url":"https://api.github.com/users/thus/gists{/gist_id}","starred_url":"https://api.github.com/users/thus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thus/subscriptions","organizations_url":"https://api.github.com/users/thus/orgs","repos_url":"https://api.github.com/users/thus/repos","events_url":"https://api.github.com/users/thus/events{/privacy}","received_events_url":"https://api.github.com/users/thus/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/thus/suricata","description":"My personal development tree for Suricata","fork":true,"url":"https://api.github.com/repos/thus/suricata","forks_url":"https://api.github.com/repos/thus/suricata/forks","keys_url":"https://api.github.com/repos/thus/suricata/keys{/key_id}","collaborators_url":"https://api.github.com/repos/thus/suricata/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/thus/suricata/teams","hooks_url":"https://api.github.com/repos/thus/suricata/hooks","issue_events_url":"https://api.github.com/repos/thus/suricata/issues/events{/number}","events_url":"https://api.github.com/repos/thus/suricata/events","assignees_url":"https://api.github.com/repos/thus/suricata/assignees{/user}","branches_url":"https://api.github.com/repos/thus/suricata/branches{/branch}","tags_url":"https://api.github.com/repos/thus/suricata/tags","blobs_url":"https://api.github.com/repos/thus/suricata/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/thus/suricata/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/thus/suricata/git/refs{/sha}","trees_url":"https://api.github.com/repos/thus/suricata/git/trees{/sha}","statuses_url":"https://api.github.com/repos/thus/suricata/statuses/{sha}","languages_url":"https://api.github.com/repos/thus/suricata/languages","stargazers_url":"https://api.github.com/repos/thus/suricata/stargazers","contributors_url":"https://api.github.com/repos/thus/suricata/contributors","subscribers_url":"https://api.github.com/repos/thus/suricata/subscribers","subscription_url":"https://api.github.com/repos/thus/suricata/subscription","commits_url":"https://api.github.com/repos/thus/suricata/commits{/sha}","git_commits_url":"https://api.github.com/repos/thus/suricata/git/commits{/sha}","comments_url":"https://api.github.com/repos/thus/suricata/comments{/number}","issue_comment_url":"https://api.github.com/repos/thus/suricata/issues/comments{/number}","contents_url":"https://api.github.com/repos/thus/suricata/contents/{+path}","compare_url":"https://api.github.com/repos/thus/suricata/compare/{base}...{head}","merges_url":"https://api.github.com/repos/thus/suricata/merges","archive_url":"https://api.github.com/repos/thus/suricata/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/thus/suricata/downloads","issues_url":"https://api.github.com/repos/thus/suricata/issues{/number}","pulls_url":"https://api.github.com/repos/thus/suricata/pulls{/number}","milestones_url":"https://api.github.com/repos/thus/suricata/milestones{/number}","notifications_url":"https://api.github.com/repos/thus/suricata/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/thus/suricata/labels{/name}","releases_url":"https://api.github.com/repos/thus/suricata/releases{/id}","deployments_url":"https://api.github.com/repos/thus/suricata/deployments","created_at":"2015-09-30T08:23:02Z","updated_at":"2016-12-16T12:01:04Z","pushed_at":"2018-02-05T09:39:52Z","git_url":"git://github.com/thus/suricata.git","ssh_url":"git@github.com:thus/suricata.git","clone_url":"https://github.com/thus/suricata.git","svn_url":"https://github.com/thus/suricata","homepage":"","size":37126,"stargazers_count":0,"watchers_count":0,"language":"C","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"gpl-2.0","name":"GNU General Public License v2.0","spdx_id":"GPL-2.0","url":"https://api.github.com/licenses/gpl-2.0"},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"OISF:master","ref":"master","sha":"d2121945c93ea7db0454a2865c8696b940df477a","user":{"login":"OISF","id":2188963,"avatar_url":"https://avatars3.githubusercontent.com/u/2188963?v=4","gravatar_id":"","url":"https://api.github.com/users/OISF","html_url":"https://github.com/OISF","followers_url":"https://api.github.com/users/OISF/followers","following_url":"https://api.github.com/users/OISF/following{/other_user}","gists_url":"https://api.github.com/users/OISF/gists{/gist_id}","starred_url":"https://api.github.com/users/OISF/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OISF/subscriptions","organizations_url":"https://api.github.com/users/OISF/orgs","repos_url":"https://api.github.com/users/OISF/repos","events_url":"https://api.github.com/users/OISF/events{/privacy}","received_events_url":"https://api.github.com/users/OISF/received_events","type":"Organization","site_admin":false},"repo":{"id":5410234,"name":"suricata","full_name":"OISF/suricata","owner":{"login":"OISF","id":2188963,"avatar_url":"https://avatars3.githubusercontent.com/u/2188963?v=4","gravatar_id":"","url":"https://api.github.com/users/OISF","html_url":"https://github.com/OISF","followers_url":"https://api.github.com/users/OISF/followers","following_url":"https://api.github.com/users/OISF/following{/other_user}","gists_url":"https://api.github.com/users/OISF/gists{/gist_id}","starred_url":"https://api.github.com/users/OISF/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/OISF/subscriptions","organizations_url":"https://api.github.com/users/OISF/orgs","repos_url":"https://api.github.com/users/OISF/repos","events_url":"https://api.github.com/users/OISF/events{/privacy}","received_events_url":"https://api.github.com/users/OISF/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/OISF/suricata","description":"Suricata git repository maintained by the OISF","fork":false,"url":"https://api.github.com/repos/OISF/suricata","forks_url":"https://api.github.com/repos/OISF/suricata/forks","keys_url":"https://api.github.com/repos/OISF/suricata/keys{/key_id}","collaborators_url":"https://api.github.com/repos/OISF/suricata/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/OISF/suricata/teams","hooks_url":"https://api.github.com/repos/OISF/suricata/hooks","issue_events_url":"https://api.github.com/repos/OISF/suricata/issues/events{/number}","events_url":"https://api.github.com/repos/OISF/suricata/events","assignees_url":"https://api.github.com/repos/OISF/suricata/assignees{/user}","branches_url":"https://api.github.com/repos/OISF/suricata/branches{/branch}","tags_url":"https://api.github.com/repos/OISF/suricata/tags","blobs_url":"https://api.github.com/repos/OISF/suricata/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/OISF/suricata/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/OISF/suricata/git/refs{/sha}","trees_url":"https://api.github.com/repos/OISF/suricata/git/trees{/sha}","statuses_url":"https://api.github.com/repos/OISF/suricata/statuses/{sha}","languages_url":"https://api.github.com/repos/OISF/suricata/languages","stargazers_url":"https://api.github.com/repos/OISF/suricata/stargazers","contributors_url":"https://api.github.com/repos/OISF/suricata/contributors","subscribers_url":"https://api.github.com/repos/OISF/suricata/subscribers","subscription_url":"https://api.github.com/repos/OISF/suricata/subscription","commits_url":"https://api.github.com/repos/OISF/suricata/commits{/sha}","git_commits_url":"https://api.github.com/repos/OISF/suricata/git/commits{/sha}","comments_url":"https://api.github.com/repos/OISF/suricata/comments{/number}","issue_comment_url":"https://api.github.com/repos/OISF/suricata/issues/comments{/number}","contents_url":"https://api.github.com/repos/OISF/suricata/contents/{+path}","compare_url":"https://api.github.com/repos/OISF/suricata/compare/{base}...{head}","merges_url":"https://api.github.com/repos/OISF/suricata/merges","archive_url":"https://api.github.com/repos/OISF/suricata/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/OISF/suricata/downloads","issues_url":"https://api.github.com/repos/OISF/suricata/issues{/number}","pulls_url":"https://api.github.com/repos/OISF/suricata/pulls{/number}","milestones_url":"https://api.github.com/repos/OISF/suricata/milestones{/number}","notifications_url":"https://api.github.com/repos/OISF/suricata/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/OISF/suricata/labels{/name}","releases_url":"https://api.github.com/repos/OISF/suricata/releases{/id}","deployments_url":"https://api.github.com/repos/OISF/suricata/deployments","created_at":"2012-08-14T08:30:06Z","updated_at":"2018-02-07T16:05:17Z","pushed_at":"2018-02-07T13:24:50Z","git_url":"git://github.com/OISF/suricata.git","ssh_url":"git@github.com:OISF/suricata.git","clone_url":"https://github.com/OISF/suricata.git","svn_url":"https://github.com/OISF/suricata","homepage":"http://suricata-ids.org/","size":36658,"stargazers_count":571,"watchers_count":571,"language":"C","has_issues":false,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":416,"mirror_url":null,"archived":false,"open_issues_count":22,"license":{"key":"gpl-2.0","name":"GNU General Public License v2.0","spdx_id":"GPL-2.0","url":"https://api.github.com/licenses/gpl-2.0"},"forks":416,"open_issues":22,"watchers":571,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/OISF/suricata/pulls/3215"},"html":{"href":"https://github.com/OISF/suricata/pull/3215"},"issue":{"href":"https://api.github.com/repos/OISF/suricata/issues/3215"},"comments":{"href":"https://api.github.com/repos/OISF/suricata/issues/3215/comments"},"review_comments":{"href":"https://api.github.com/repos/OISF/suricata/pulls/3215/comments"},"review_comment":{"href":"https://api.github.com/repos/OISF/suricata/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/OISF/suricata/pulls/3215/commits"},"statuses":{"href":"https://api.github.com/repos/OISF/suricata/statuses/11c3aa05ebd7b9b15a194eb1c0791375f97dcda7"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"victorjulien"}}