{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/comments/40427391","id":40427391,"diff_hunk":"@@ -719,6 +719,224 @@ GetX509NameInfo(\n \n /*\n Function:\n+CheckX509HostnameMatch\n+\n+Checks if a particular ASN1_STRING represents the entry in a certificate which would match against\n+the requested hostname.\n+\n+Prameter sanRules: 0 for match rules against the subject CN, 1 for match rules against a SAN entry\n+\n+Return values:\n+1 if the hostname is a match\n+0 if the hostname is not a match\n+Any negative number indicates an error in the arguments.\n+*/\n+static\n+int\n+CheckX509HostnameMatch(ASN1_STRING* candidate, const char* hostname, int cchHostname, char sanRules)\n+{\n+    assert(candidate);\n+    assert(hostname);\n+\n+    if (!candidate->data || !candidate->length)\n+    {\n+        return 0;\n+    }\n+\n+    // If the candidate is *.example.org then the smallest we would match is a.example.org, which is the same\n+    // length. So anything longer than what we're matching against isn't valid.\n+\n+    // This assumption might not hold under IDNA, it might need to be more sophisticated\n+    // \"UTF character string length\"\n+    if (candidate->length > cchHostname)\n+    {\n+        return 0;\n+    }\n+\n+    if (sanRules)\n+    {\n+        // RFC2818 says to use RFC2595 matching rules, but then gives an example that f*.com would match foo.com\n+        // RFC2595 says that '*' may be used as the left name component, in which case it is a wildcard that does\n+        // not match a '.'.\n+        //\n+        // In the interest of time, and the idea that it's better to err on the side of more restrictive,\n+        // this implementation does not support mid-string wildcards.\n+        //\n+        // TODO (3444): Determine if we're too restrictive here.\n+\n+        char* candidateStr;\n+        int i;\n+        int hostnameFirstDot = -1;\n+\n+        // A GEN_DNS name is supposed to be a V_ASN1_IA5STRING.  If it isn't, we don't know how to read it.\n+        if (candidate->type != V_ASN1_IA5STRING)\n+        {\n+            return 0;\n+        }\n+\n+        // Great, candidateStr is just candidate->data!\n+        candidateStr = (char*)candidate->data;\n+\n+        // First, verify that the string is alphanumeric, plus hyphens or periods and maybe starting with an asterisk.\n+        for (i = 0; i < candidate->length; ++i)\n+        {\n+            char c = candidateStr[i];\n+\n+            if ((c < 'a' || c > 'z') &&\n+                (c < '0' || c > '9') &&\n+                (c != '.') &&\n+                (c != '-') &&\n+                (c != '*' || i != 0))","path":"src/Native/System.Security.Cryptography.Native/openssl.c","position":71,"original_position":71,"commit_id":"2d5ad288aba867066163c552d9fa80cd1943a99d","original_commit_id":"2d5ad288aba867066163c552d9fa80cd1943a99d","user":{"login":"stephentoub","id":2642209,"avatar_url":"https://avatars.githubusercontent.com/u/2642209?v=3","gravatar_id":"","url":"https://api.github.com/users/stephentoub","html_url":"https://github.com/stephentoub","followers_url":"https://api.github.com/users/stephentoub/followers","following_url":"https://api.github.com/users/stephentoub/following{/other_user}","gists_url":"https://api.github.com/users/stephentoub/gists{/gist_id}","starred_url":"https://api.github.com/users/stephentoub/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stephentoub/subscriptions","organizations_url":"https://api.github.com/users/stephentoub/orgs","repos_url":"https://api.github.com/users/stephentoub/repos","events_url":"https://api.github.com/users/stephentoub/events{/privacy}","received_events_url":"https://api.github.com/users/stephentoub/received_events","type":"User","site_admin":false},"body":"I believe it's correct as is.  After checking the rest of the characters and finding it's thus far invalid, we check to see if it's a '*'.  If it's not, then the condition ```c != '*'``` is satisfied and we return 0 correctly as an error.  If it is a '*', then ```c != '*'``` is false and we proceed to check ```i != 0```... if it's the first character, then ```i != 0``` is false and we don't error out; if it's not the first character, then ```i != 0``` is true and we return 0 correctly.","created_at":"2015-09-25T13:11:31Z","updated_at":"2015-09-25T13:11:31Z","html_url":"https://github.com/dotnet/corefx/pull/3449#discussion_r40427391","pull_request_url":"https://api.github.com/repos/dotnet/corefx/pulls/3449","_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments/40427391"},"html":{"href":"https://github.com/dotnet/corefx/pull/3449#discussion_r40427391"},"pull_request":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3449"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/3449","id":45976015,"html_url":"https://github.com/dotnet/corefx/pull/3449","diff_url":"https://github.com/dotnet/corefx/pull/3449.diff","patch_url":"https://github.com/dotnet/corefx/pull/3449.patch","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/3449","number":3449,"state":"open","locked":false,"title":"Validate hostname when using SslStream as a client","user":{"login":"bartonjs","id":10642668,"avatar_url":"https://avatars.githubusercontent.com/u/10642668?v=3","gravatar_id":"","url":"https://api.github.com/users/bartonjs","html_url":"https://github.com/bartonjs","followers_url":"https://api.github.com/users/bartonjs/followers","following_url":"https://api.github.com/users/bartonjs/following{/other_user}","gists_url":"https://api.github.com/users/bartonjs/gists{/gist_id}","starred_url":"https://api.github.com/users/bartonjs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bartonjs/subscriptions","organizations_url":"https://api.github.com/users/bartonjs/orgs","repos_url":"https://api.github.com/users/bartonjs/repos","events_url":"https://api.github.com/users/bartonjs/events{/privacy}","received_events_url":"https://api.github.com/users/bartonjs/received_events","type":"User","site_admin":false},"body":"Added a method in the crypto shim (CheckX509Hostname) which does the heavy lifting. It may end up making sense to push this up into managed for better flexibility when trying to add support for IDNA; but that would be greatly assisted by having good managed decoders for the subject name pieces and the SubjectAltNames extension.\r\n\r\nVerified that it works against an explicit SAN entry and a wildcard SAN entry.","created_at":"2015-09-25T04:20:41Z","updated_at":"2015-09-25T13:11:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d75dadeb15b69642f9ddd4327f23472d6f65c942","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dotnet/corefx/pulls/3449/commits","review_comments_url":"https://api.github.com/repos/dotnet/corefx/pulls/3449/comments","review_comment_url":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/3449/comments","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/2d5ad288aba867066163c552d9fa80cd1943a99d","head":{"label":"bartonjs:sslstream_unix_checkname","ref":"sslstream_unix_checkname","sha":"2d5ad288aba867066163c552d9fa80cd1943a99d","user":{"login":"bartonjs","id":10642668,"avatar_url":"https://avatars.githubusercontent.com/u/10642668?v=3","gravatar_id":"","url":"https://api.github.com/users/bartonjs","html_url":"https://github.com/bartonjs","followers_url":"https://api.github.com/users/bartonjs/followers","following_url":"https://api.github.com/users/bartonjs/following{/other_user}","gists_url":"https://api.github.com/users/bartonjs/gists{/gist_id}","starred_url":"https://api.github.com/users/bartonjs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bartonjs/subscriptions","organizations_url":"https://api.github.com/users/bartonjs/orgs","repos_url":"https://api.github.com/users/bartonjs/repos","events_url":"https://api.github.com/users/bartonjs/events{/privacy}","received_events_url":"https://api.github.com/users/bartonjs/received_events","type":"User","site_admin":false},"repo":{"id":29888389,"name":"corefx","full_name":"bartonjs/corefx","owner":{"login":"bartonjs","id":10642668,"avatar_url":"https://avatars.githubusercontent.com/u/10642668?v=3","gravatar_id":"","url":"https://api.github.com/users/bartonjs","html_url":"https://github.com/bartonjs","followers_url":"https://api.github.com/users/bartonjs/followers","following_url":"https://api.github.com/users/bartonjs/following{/other_user}","gists_url":"https://api.github.com/users/bartonjs/gists{/gist_id}","starred_url":"https://api.github.com/users/bartonjs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bartonjs/subscriptions","organizations_url":"https://api.github.com/users/bartonjs/orgs","repos_url":"https://api.github.com/users/bartonjs/repos","events_url":"https://api.github.com/users/bartonjs/events{/privacy}","received_events_url":"https://api.github.com/users/bartonjs/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bartonjs/corefx","description":"This repository contains the foundational libraries that make up the .NET Core development stack.","fork":true,"url":"https://api.github.com/repos/bartonjs/corefx","forks_url":"https://api.github.com/repos/bartonjs/corefx/forks","keys_url":"https://api.github.com/repos/bartonjs/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bartonjs/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bartonjs/corefx/teams","hooks_url":"https://api.github.com/repos/bartonjs/corefx/hooks","issue_events_url":"https://api.github.com/repos/bartonjs/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/bartonjs/corefx/events","assignees_url":"https://api.github.com/repos/bartonjs/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/bartonjs/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/bartonjs/corefx/tags","blobs_url":"https://api.github.com/repos/bartonjs/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bartonjs/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bartonjs/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/bartonjs/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bartonjs/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/bartonjs/corefx/languages","stargazers_url":"https://api.github.com/repos/bartonjs/corefx/stargazers","contributors_url":"https://api.github.com/repos/bartonjs/corefx/contributors","subscribers_url":"https://api.github.com/repos/bartonjs/corefx/subscribers","subscription_url":"https://api.github.com/repos/bartonjs/corefx/subscription","commits_url":"https://api.github.com/repos/bartonjs/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/bartonjs/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/bartonjs/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/bartonjs/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/bartonjs/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/bartonjs/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bartonjs/corefx/merges","archive_url":"https://api.github.com/repos/bartonjs/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bartonjs/corefx/downloads","issues_url":"https://api.github.com/repos/bartonjs/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/bartonjs/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/bartonjs/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/bartonjs/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bartonjs/corefx/labels{/name}","releases_url":"https://api.github.com/repos/bartonjs/corefx/releases{/id}","created_at":"2015-01-26T23:55:53Z","updated_at":"2015-08-21T07:07:58Z","pushed_at":"2015-09-25T04:14:53Z","git_url":"git://github.com/bartonjs/corefx.git","ssh_url":"git@github.com:bartonjs/corefx.git","clone_url":"https://github.com/bartonjs/corefx.git","svn_url":"https://github.com/bartonjs/corefx","homepage":"","size":32177,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dotnet:dev-sslstream","ref":"dev-sslstream","sha":"0ce6be21666fb9273528da7ce32bc2e8e8b77897","user":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"repo":{"id":26295345,"name":"corefx","full_name":"dotnet/corefx","owner":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dotnet/corefx","description":"This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others.","fork":false,"url":"https://api.github.com/repos/dotnet/corefx","forks_url":"https://api.github.com/repos/dotnet/corefx/forks","keys_url":"https://api.github.com/repos/dotnet/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotnet/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotnet/corefx/teams","hooks_url":"https://api.github.com/repos/dotnet/corefx/hooks","issue_events_url":"https://api.github.com/repos/dotnet/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/dotnet/corefx/events","assignees_url":"https://api.github.com/repos/dotnet/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/dotnet/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/dotnet/corefx/tags","blobs_url":"https://api.github.com/repos/dotnet/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotnet/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotnet/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotnet/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/dotnet/corefx/languages","stargazers_url":"https://api.github.com/repos/dotnet/corefx/stargazers","contributors_url":"https://api.github.com/repos/dotnet/corefx/contributors","subscribers_url":"https://api.github.com/repos/dotnet/corefx/subscribers","subscription_url":"https://api.github.com/repos/dotnet/corefx/subscription","commits_url":"https://api.github.com/repos/dotnet/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotnet/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotnet/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotnet/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotnet/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/dotnet/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotnet/corefx/merges","archive_url":"https://api.github.com/repos/dotnet/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotnet/corefx/downloads","issues_url":"https://api.github.com/repos/dotnet/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/dotnet/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/dotnet/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/dotnet/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotnet/corefx/labels{/name}","releases_url":"https://api.github.com/repos/dotnet/corefx/releases{/id}","created_at":"2014-11-06T23:42:48Z","updated_at":"2015-09-25T07:59:55Z","pushed_at":"2015-09-25T13:02:15Z","git_url":"git://github.com/dotnet/corefx.git","ssh_url":"git@github.com:dotnet/corefx.git","clone_url":"https://github.com/dotnet/corefx.git","svn_url":"https://github.com/dotnet/corefx","homepage":"http://dotnet.github.io/core/","size":71664,"stargazers_count":8381,"watchers_count":8381,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1811,"mirror_url":null,"open_issues_count":604,"forks":1811,"open_issues":604,"watchers":8381,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3449"},"html":{"href":"https://github.com/dotnet/corefx/pull/3449"},"issue":{"href":"https://api.github.com/repos/dotnet/corefx/issues/3449"},"comments":{"href":"https://api.github.com/repos/dotnet/corefx/issues/3449/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3449/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3449/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/corefx/statuses/2d5ad288aba867066163c552d9fa80cd1943a99d"}}}}