/** * \brief this function is used to add the parsed "fingerprint" option * \brief into the current signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param id pointer to the user provided "fingerprint" option * * \retval 0 on Success * \retval -1 on Failure */ static int DetectTlsFingerprintSetup (DetectEngineCtx *de_ctx, Signature *s, const char *str) { DetectTlsData *tls = NULL; SigMatch *sm = NULL; if (DetectSignatureSetAppProto(s, ALPROTO_TLS) != 0) return -1; tls = DetectTlsFingerprintParse(str, s->init_data->negated); if (tls == NULL) goto error; /* Okay so far so good, lets get this into a SigMatch * and put it in the Signature. */ sm = SigMatchAlloc(); if (sm == NULL) goto error; sm->type = DETECT_AL_TLS_FINGERPRINT; sm->ctx = (void *)tls; SigMatchAppendSMToList(s, sm, g_tls_cert_list_id); return 0; error: if (tls != NULL) DetectTlsFingerprintFree(tls); if (sm != NULL) SCFree(sm); return -1; }
/** * \brief this function is used to add the parsed "fingerprint" option * \brief into the current signature * * \param de_ctx pointer to the Detection Engine Context * \param s pointer to the Current Signature * \param id pointer to the user provided "fingerprint" option * * \retval 0 on Success * \retval -1 on Failure */ static int DetectTlsFingerprintSetup (DetectEngineCtx *de_ctx, Signature *s, char *str) { DetectTlsData *tls = NULL; SigMatch *sm = NULL; tls = DetectTlsFingerprintParse(str); if (tls == NULL) goto error; /* Okay so far so good, lets get this into a SigMatch * and put it in the Signature. */ sm = SigMatchAlloc(); if (sm == NULL) goto error; if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_TLS) { SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); goto error; } sm->type = DETECT_AL_TLS_FINGERPRINT; sm->ctx = (void *)tls; s->flags |= SIG_FLAG_APPLAYER; s->alproto = ALPROTO_TLS; SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); return 0; error: if (tls != NULL) DetectTlsFingerprintFree(tls); if (sm != NULL) SCFree(sm); return -1; }
/** * \brief This function is used to parse fingerprint passed via keyword: "fingerprint" * * \param idstr Pointer to the user provided fingerprint option * * \retval pointer to DetectTlsData on success * \retval NULL on failure */ static DetectTlsData *DetectTlsFingerprintParse (char *str) { DetectTlsData *tls = NULL; #define MAX_SUBSTRINGS 30 int ret = 0, res = 0; int ov[MAX_SUBSTRINGS]; const char *str_ptr; char *orig; char *tmp_str; uint32_t flag = 0; ret = pcre_exec(fingerprint_parse_regex, fingerprint_parse_regex_study, str, strlen(str), 0, 0, ov, MAX_SUBSTRINGS); if (ret != 3) { SCLogError(SC_ERR_PCRE_MATCH, "invalid tls.fingerprint option"); goto error; } res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 1, &str_ptr); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); goto error; } if (str_ptr[0] == '!') flag = DETECT_CONTENT_NEGATED; res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 2, &str_ptr); if (res < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); goto error; } /* We have a correct id option */ tls = SCMalloc(sizeof(DetectTlsData)); if (unlikely(tls == NULL)) goto error; tls->fingerprint = NULL; tls->flags = flag; orig = SCStrdup((char*)str_ptr); if (unlikely(orig == NULL)) { goto error; } tmp_str=orig; /* Let's see if we need to escape "'s */ if (tmp_str[0] == '"') { tmp_str[strlen(tmp_str) - 1] = '\0'; tmp_str += 1; } tls->fingerprint = SCStrdup(tmp_str); if (tls->fingerprint == NULL) { SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate fingerprint"); } SCFree(orig); SCLogDebug("will look for TLS fingerprint %s", tls->fingerprint); return tls; error: if (tls != NULL) DetectTlsFingerprintFree(tls); return NULL; }