{"action":"created","issue":{"url":"https://api.github.com/repos/AFNetworking/AFNetworking/issues/2733","labels_url":"https://api.github.com/repos/AFNetworking/AFNetworking/issues/2733/labels{/name}","comments_url":"https://api.github.com/repos/AFNetworking/AFNetworking/issues/2733/comments","events_url":"https://api.github.com/repos/AFNetworking/AFNetworking/issues/2733/events","html_url":"https://github.com/AFNetworking/AFNetworking/pull/2733","id":77667846,"number":2733,"title":"Implemented Public Key Hash Pinning","user":{"login":"arein","id":966091,"avatar_url":"https://avatars.githubusercontent.com/u/966091?v=3","gravatar_id":"","url":"https://api.github.com/users/arein","html_url":"https://github.com/arein","followers_url":"https://api.github.com/users/arein/followers","following_url":"https://api.github.com/users/arein/following{/other_user}","gists_url":"https://api.github.com/users/arein/gists{/gist_id}","starred_url":"https://api.github.com/users/arein/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arein/subscriptions","organizations_url":"https://api.github.com/users/arein/orgs","repos_url":"https://api.github.com/users/arein/repos","events_url":"https://api.github.com/users/arein/events{/privacy}","received_events_url":"https://api.github.com/users/arein/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/AFNetworking/AFNetworking/labels/enhancement","name":"enhancement","color":"2D8DFF"},{"url":"https://api.github.com/repos/AFNetworking/AFNetworking/labels/needs%20feedback","name":"needs feedback","color":"9559F0"},{"url":"https://api.github.com/repos/AFNetworking/AFNetworking/labels/security","name":"security","color":"69B805"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/AFNetworking/AFNetworking/milestones/2","html_url":"https://github.com/AFNetworking/AFNetworking/milestones/2.6.0","labels_url":"https://api.github.com/repos/AFNetworking/AFNetworking/milestones/2/labels","id":1097139,"number":2,"title":"2.6.0","description":"","creator":{"login":"kcharwood","id":198768,"avatar_url":"https://avatars.githubusercontent.com/u/198768?v=3","gravatar_id":"","url":"https://api.github.com/users/kcharwood","html_url":"https://github.com/kcharwood","followers_url":"https://api.github.com/users/kcharwood/followers","following_url":"https://api.github.com/users/kcharwood/following{/other_user}","gists_url":"https://api.github.com/users/kcharwood/gists{/gist_id}","starred_url":"https://api.github.com/users/kcharwood/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kcharwood/subscriptions","organizations_url":"https://api.github.com/users/kcharwood/orgs","repos_url":"https://api.github.com/users/kcharwood/repos","events_url":"https://api.github.com/users/kcharwood/events{/privacy}","received_events_url":"https://api.github.com/users/kcharwood/received_events","type":"User","site_admin":false},"open_issues":5,"closed_issues":0,"state":"open","created_at":"2015-05-05T15:56:08Z","updated_at":"2015-05-18T15:39:19Z","due_on":null,"closed_at":null},"comments":18,"created_at":"2015-05-18T14:01:56Z","updated_at":"2015-06-19T08:47:25Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/AFNetworking/AFNetworking/pulls/2733","html_url":"https://github.com/AFNetworking/AFNetworking/pull/2733","diff_url":"https://github.com/AFNetworking/AFNetworking/pull/2733.diff","patch_url":"https://github.com/AFNetworking/AFNetworking/pull/2733.patch"},"body":"This closes #2695 and #2673 \r\n\r\nMy implementation adds an easy way to use hashes of the Subject Public Key Info (SPKI) of certificates. It also adds a way to accept backup key(s) in case the primary key gets compromised/lost:\r\n\r\n```objectivec\r\nAFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKeyHash];\r\n[policy setValidatesCertificateChain:NO]; // This allows to use backup key(s)\r\n[policy setPinnedPublicKeyHashes:[NSArray arrayWithObjects:@\"G2bwK+Vdcc6RPUi2h2A9mOPezwc=\", @\"backupkeyhash\", nil]];\r\n```\r\n\r\nThe hashes can be retrieved like this. Let's assume that we want to pin google.com:\r\n\r\n```bash\r\nopenssl s_client -showcerts -connect google.com:443 # Get google.com Certificate Chain\r\n# Create a file called \"google.com.crt\" from the leaf certificate\r\nopenssl x509 -inform PEM -pubkey -noout -in google.com.crt | openssl pkey -pubin -outform DER | openssl dgst -sha1 -binary | openssl enc -base64\r\n```\r\n\r\nThe main implementation challenge was that extracting a public key using Cocoa's security library returns a subset of the information that you would usually find in an ASN.1 encoded public key. Luckily, I found [this](http://blog.wingsofhermes.org/?p=42) blog post that outlines how to pad the public key."},"comment":{"url":"https://api.github.com/repos/AFNetworking/AFNetworking/issues/comments/113435674","html_url":"https://github.com/AFNetworking/AFNetworking/pull/2733#issuecomment-113435674","issue_url":"https://api.github.com/repos/AFNetworking/AFNetworking/issues/2733","id":113435674,"user":{"login":"asnare","id":401970,"avatar_url":"https://avatars.githubusercontent.com/u/401970?v=3","gravatar_id":"","url":"https://api.github.com/users/asnare","html_url":"https://github.com/asnare","followers_url":"https://api.github.com/users/asnare/followers","following_url":"https://api.github.com/users/asnare/following{/other_user}","gists_url":"https://api.github.com/users/asnare/gists{/gist_id}","starred_url":"https://api.github.com/users/asnare/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/asnare/subscriptions","organizations_url":"https://api.github.com/users/asnare/orgs","repos_url":"https://api.github.com/users/asnare/repos","events_url":"https://api.github.com/users/asnare/events{/privacy}","received_events_url":"https://api.github.com/users/asnare/received_events","type":"User","site_admin":false},"created_at":"2015-06-19T08:47:25Z","updated_at":"2015-06-19T08:47:25Z","body":"Sorry for taking so long to get back to you, but we're fine with relicensing the DER decoder that I wrote.\r\n\r\nI should explain that I didn't license it as open-source originally because I was concerned about how robust/secure it was. In particular, I reasoned that it's code that would end up being an inviting attack surface for an adversary that was trying to compromise the certificate chain. I didn't think it was ethical to just put it _out there_ until I was reasonably confident it was safe to use. (DER-decoding is sufficiently esoteric that the _many-eyeballs-make-for-shallow-bugs_ argument doesn't necessarily hold.)\r\n\r\nIn the interim, this code has been used in several fairly high-profile applications that were subject to external security (code-level) reviews. Even though I wasn't personally involved in these projects, they give me sufficient confidence to assuage my concerns.\r\n\r\nPlease let me know if there's anything I need to do formally to effect the relicensing."}}