{"action":"created","comment":{"url":"https://api.github.com/repos/cryptosense/key-parsers/pulls/comments/75700430","id":75700430,"diff_hunk":"@@ -0,0 +1,280 @@\n+let try_with_asn f = try Result.Ok (f ()) with Asn.Parse_error s -> Result.Error s\n+let raise_asn f = match f () with Result.Ok x -> x | Result.Error s -> Asn.parse_error s\n+\n+let pp_of_to_string to_string fmt x =\n+  Format.pp_print_string fmt (to_string x)\n+\n+module Asn = struct\n+  include (Asn : module type of Asn with module OID := Asn.OID and type 'a t = 'a Asn.t)\n+\n+  module OID = struct\n+    include Asn.OID\n+    let pp = pp_of_to_string to_string\n+    let compare a b =\n+      String.compare (to_string a) (to_string b)\n+\n+    let of_yojson = function\n+      | `String s -> Result.Ok (Asn.OID.of_string s)\n+      | _ -> Result.Error \"Cannot convert this json value to Asn.OID.t\"\n+\n+    let to_yojson oid =\n+      `String (Asn.OID.to_string oid)\n+  end\n+end\n+\n+module Z = struct\n+  include Z\n+  let pp = pp_of_to_string to_string\n+\n+  let of_yojson = function\n+    | `String s -> Result.Ok (Z.of_string s)\n+    | _ -> Result.Error \"Cannot convert this json value to Z.t\"\n+\n+  let to_yojson z =\n+    `String (Z.to_string z)\n+end\n+module RSA =\n+struct\n+  module Public =\n+  struct\n+    type t = {\n+      n: Z.t;\n+      e: Z.t;\n+    }\n+    [@@deriving ord,yojson,eq,show]\n+  end\n+end\n+\n+module ECDSA =\n+struct\n+  module Public =\n+  struct\n+    type t =\n+      { modulus : Z.t\n+      ; coefficient_a : Z.t\n+      ; coefficient_b : Z.t\n+      ; base_point_g : Z.t\n+      ; base_point_r_order : Z.t\n+      ; public_point_y : Z.t\n+      ; cofactor_f : Z.t\n+      }\n+      [@@deriving ord,yojson,eq,show]\n+  end\n+end\n+\n+let rsa_oid = Asn.OID.of_string \"0.4.0.127.0.7.2.2.2.1.4\"\n+let ecdsa_oid = Asn.OID.of_string \"0.4.0.127.0.7.2.2.2.2.3\"\n+\n+type t =\n+  [ `RSA of RSA.Public.t | `ECDSA of ECDSA.Public.t | `UNKNOWN ]\n+\n+type algo_typ =\n+  | RSA\n+  | ECDSA\n+  | Unknown of Asn.OID.t\n+\n+type parser_state =\n+  | Init\n+  | Type\n+  | Length\n+  | Value of int\n+\n+let cvc_object_types =\n+  [ 0x7F49, (`PUBLIC_KEY, true)\n+  ; 0x06, (`OID, false)\n+  ; 0x81, (`MODULUS, false)\n+  ; 0x82, (`EXPONENT, false)\n+  ; 0x82, (`COEFFICIENT_A, false)\n+  ; 0x83, (`COEFFICIENT_B, false)\n+  ; 0x84, (`BASE_POINT_G, false)\n+  ; 0x85, (`BASE_POINT_R_ORDER, false)\n+  ; 0x86, (`PUBLIC_POINT_Y, false)\n+  ; 0x87, (`COFACTOR_F, false)\n+  ]\n+\n+let find_cvc_object_type tag =\n+  let code = Cstruct.get_uint8 tag 0 in\n+  try code, List.assoc code cvc_object_types\n+  with Not_found ->\n+    let code =\n+      let msb = code * 0x100 in\n+      let lsb = Cstruct.get_uint8 tag 1 in\n+      msb + lsb\n+    in\n+    code, List.assoc code cvc_object_types\n+\n+(* utility function to parse a big-endian blob as a Z.t *)\n+let atoz_bigendian s =\n+  let reverse s =\n+    let n = String.length s in\n+    String.init n (fun i -> s.[n-1-i])\n+  in\n+  Z.of_bits @@ reverse @@ Cstruct.to_string s\n+\n+let grammar =\n+  let open Asn in\n+  let f = function\n+    | oid when oid = rsa_oid -> RSA\n+    | oid when oid = ecdsa_oid -> ECDSA\n+    | oid -> Unknown oid in\n+  let g = function\n+    | RSA -> rsa_oid\n+    | ECDSA -> ecdsa_oid\n+    | Unknown oid -> oid in\n+  map f g oid\n+\n+let decode_oid str =\n+  let t, left = Asn.(decode_exn (codec ber grammar) str) in\n+  if Cstruct.len left = 0 then t\n+  else Asn.parse_error \"CVC: OID with leftover\"\n+\n+let decode bytes =\n+  let buffer = Cstruct.create 4_096 in\n+  (* FSM to produce `Type ..., `Length ..., `Value ... tokens from a blob.\n+   * This tries to exploit tailcall recursion as much as possible in order to\n+   * avoid a stack explosion\n+   *)\n+  let rec tokenize ~acc bytes i lim state = function\n+    | Init ->\n+        if i >= lim then List.rev acc\n+        else tokenize ~acc bytes i lim None Type\n+    | Type ->\n+        Cstruct.blit bytes i buffer 0 2;\n+        let cvc_type = find_cvc_object_type buffer in\n+        let acc = `Type cvc_type :: acc in\n+        begin match cvc_type with\n+          | tag, _ when tag <= 0xff ->\n+              let i = i + 1 in\n+              (tokenize[@tailcall]) ~acc bytes i lim (Some cvc_type) Length\n+          | tag, _ ->\n+              let i = i + 2 in\n+              (tokenize[@tailcall]) ~acc bytes i lim (Some cvc_type) Length\n+        end\n+    | Length ->\n+        let code = Cstruct.get_uint8 bytes i in\n+        if code < 0x80\n+        then begin\n+          let i = i + 1 in\n+          (tokenize[@tailcall]) ~acc:((`Length code) :: acc) bytes i lim state (Value code)\n+        end\n+        else\n+          begin match code with\n+            | 0x81 ->\n+                let code = Cstruct.get_uint8 bytes (i + 1) in\n+                let i = i + 2 in\n+                (tokenize[@tailcall]) ~acc:((`Length code) :: acc) bytes i lim state (Value code)\n+            | 0x82 ->\n+                let code = Cstruct.BE.get_uint16 bytes (i + 1) in\n+                let i = i + 3 in\n+                (tokenize[@tailcall]) ~acc:((`Length code) :: acc) bytes i lim state (Value code)\n+            | _ ->\n+                raise (Failure \"Invalid LENGTH field in TLV encoded CVC data\")\n+          end\n+    | Value length ->\n+        let is_rec =\n+          match state with\n+            | None -> false\n+            | Some (_, (_, x)) -> x\n+        in\n+        let acc =\n+          if is_rec\n+          then\n+            `Value (tokenize ~acc:[] bytes i (i + length) None Init) :: acc\n+          else\n+            let bytes' =\n+              Cstruct.sub bytes i length\n+            in\n+            `Bytes bytes' :: acc\n+        in\n+        (if length + i >= Cstruct.len bytes then List.rev acc else (tokenize[@tailcall]) ~acc bytes (i + length) lim None Init)\n+  in\n+  let tokens = tokenize ~acc:[] bytes 0 (Cstruct.len bytes) None Init in\n+  let rec parse = function\n+    | `Type (_, (`PUBLIC_KEY, _)) :: `Length _ :: `Value ls :: _ ->\n+        parse ls\n+    | `Type (_, (`OID, _)) :: `Length _ :: `Bytes bytes :: tl ->\n+        let bytes =\n+          let prefix =\n+            Printf.sprintf \"\\006%c\" (Char.chr (Cstruct.len bytes))\n+            |> Cstruct.of_string\n+          in\n+          Cstruct.append prefix bytes\n+        in\n+        `Oid (decode_oid bytes) :: parse tl\n+    | `Type (_, (`MODULUS, _)) :: `Length _ :: `Bytes bytes :: tl ->\n+        `Modulus (atoz_bigendian bytes) :: parse tl\n+    | `Type (0x82, ((*`EXPONENT*) _ , _)) :: `Length _ :: `Bytes bytes :: tl ->\n+        `Exponent (atoz_bigendian bytes) :: parse tl\n+    | `Type (_, (`COEFFICIENT_B, _)) :: `Length _ :: `Bytes bytes :: tl ->\n+        `Coefficient_b (atoz_bigendian bytes) :: parse tl\n+    | `Type (_, (`BASE_POINT_G, _)) :: `Length _ :: `Bytes bytes :: tl ->\n+        `Base_point_g (atoz_bigendian bytes) :: parse tl\n+    | `Type (_, (`BASE_POINT_R_ORDER, _)) :: `Length _ :: `Bytes bytes :: tl ->","path":"src/cvc.ml","position":212,"original_position":212,"commit_id":"87a68b7b2754af92d2763e8946bc06cc22153dee","original_commit_id":"87a68b7b2754af92d2763e8946bc06cc22153dee","user":{"login":"emillon","id":496345,"avatar_url":"https://avatars.githubusercontent.com/u/496345?v=3","gravatar_id":"","url":"https://api.github.com/users/emillon","html_url":"https://github.com/emillon","followers_url":"https://api.github.com/users/emillon/followers","following_url":"https://api.github.com/users/emillon/following{/other_user}","gists_url":"https://api.github.com/users/emillon/gists{/gist_id}","starred_url":"https://api.github.com/users/emillon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/emillon/subscriptions","organizations_url":"https://api.github.com/users/emillon/orgs","repos_url":"https://api.github.com/users/emillon/repos","events_url":"https://api.github.com/users/emillon/events{/privacy}","received_events_url":"https://api.github.com/users/emillon/received_events","type":"User","site_admin":false},"body":"What do those `Bytes bytes` entries correspond to?","created_at":"2016-08-22T15:34:26Z","updated_at":"2016-08-22T15:34:27Z","html_url":"https://github.com/cryptosense/key-parsers/pull/13#discussion_r75700430","pull_request_url":"https://api.github.com/repos/cryptosense/key-parsers/pulls/13","_links":{"self":{"href":"https://api.github.com/repos/cryptosense/key-parsers/pulls/comments/75700430"},"html":{"href":"https://github.com/cryptosense/key-parsers/pull/13#discussion_r75700430"},"pull_request":{"href":"https://api.github.com/repos/cryptosense/key-parsers/pulls/13"}}},"pull_request":{"url":"https://api.github.com/repos/cryptosense/key-parsers/pulls/13","id":81953387,"html_url":"https://github.com/cryptosense/key-parsers/pull/13","diff_url":"https://github.com/cryptosense/key-parsers/pull/13.diff","patch_url":"https://github.com/cryptosense/key-parsers/pull/13.patch","issue_url":"https://api.github.com/repos/cryptosense/key-parsers/issues/13","number":13,"state":"open","locked":false,"title":"Feat/cvc","user":{"login":"chrismamo1","id":3238755,"avatar_url":"https://avatars.githubusercontent.com/u/3238755?v=3","gravatar_id":"","url":"https://api.github.com/users/chrismamo1","html_url":"https://github.com/chrismamo1","followers_url":"https://api.github.com/users/chrismamo1/followers","following_url":"https://api.github.com/users/chrismamo1/following{/other_user}","gists_url":"https://api.github.com/users/chrismamo1/gists{/gist_id}","starred_url":"https://api.github.com/users/chrismamo1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chrismamo1/subscriptions","organizations_url":"https://api.github.com/users/chrismamo1/orgs","repos_url":"https://api.github.com/users/chrismamo1/repos","events_url":"https://api.github.com/users/chrismamo1/events{/privacy}","received_events_url":"https://api.github.com/users/chrismamo1/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-08-19T09:41:46Z","updated_at":"2016-08-22T15:34:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"372d4f9f952fad4d0b733485f467c0d55954b950","assignee":{"login":"emillon","id":496345,"avatar_url":"https://avatars.githubusercontent.com/u/496345?v=3","gravatar_id":"","url":"https://api.github.com/users/emillon","html_url":"https://github.com/emillon","followers_url":"https://api.github.com/users/emillon/followers","following_url":"https://api.github.com/users/emillon/following{/other_user}","gists_url":"https://api.github.com/users/emillon/gists{/gist_id}","starred_url":"https://api.github.com/users/emillon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/emillon/subscriptions","organizations_url":"https://api.github.com/users/emillon/orgs","repos_url":"https://api.github.com/users/emillon/repos","events_url":"https://api.github.com/users/emillon/events{/privacy}","received_events_url":"https://api.github.com/users/emillon/received_events","type":"User","site_admin":false},"assignees":[{"login":"emillon","id":496345,"avatar_url":"https://avatars.githubusercontent.com/u/496345?v=3","gravatar_id":"","url":"https://api.github.com/users/emillon","html_url":"https://github.com/emillon","followers_url":"https://api.github.com/users/emillon/followers","following_url":"https://api.github.com/users/emillon/following{/other_user}","gists_url":"https://api.github.com/users/emillon/gists{/gist_id}","starred_url":"https://api.github.com/users/emillon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/emillon/subscriptions","organizations_url":"https://api.github.com/users/emillon/orgs","repos_url":"https://api.github.com/users/emillon/repos","events_url":"https://api.github.com/users/emillon/events{/privacy}","received_events_url":"https://api.github.com/users/emillon/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/cryptosense/key-parsers/pulls/13/commits","review_comments_url":"https://api.github.com/repos/cryptosense/key-parsers/pulls/13/comments","review_comment_url":"https://api.github.com/repos/cryptosense/key-parsers/pulls/comments{/number}","comments_url":"https://api.github.com/repos/cryptosense/key-parsers/issues/13/comments","statuses_url":"https://api.github.com/repos/cryptosense/key-parsers/statuses/87a68b7b2754af92d2763e8946bc06cc22153dee","head":{"label":"chrismamo1:feat/CVC","ref":"feat/CVC","sha":"87a68b7b2754af92d2763e8946bc06cc22153dee","user":{"login":"chrismamo1","id":3238755,"avatar_url":"https://avatars.githubusercontent.com/u/3238755?v=3","gravatar_id":"","url":"https://api.github.com/users/chrismamo1","html_url":"https://github.com/chrismamo1","followers_url":"https://api.github.com/users/chrismamo1/followers","following_url":"https://api.github.com/users/chrismamo1/following{/other_user}","gists_url":"https://api.github.com/users/chrismamo1/gists{/gist_id}","starred_url":"https://api.github.com/users/chrismamo1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chrismamo1/subscriptions","organizations_url":"https://api.github.com/users/chrismamo1/orgs","repos_url":"https://api.github.com/users/chrismamo1/repos","events_url":"https://api.github.com/users/chrismamo1/events{/privacy}","received_events_url":"https://api.github.com/users/chrismamo1/received_events","type":"User","site_admin":false},"repo":{"id":65831930,"name":"key-parsers","full_name":"chrismamo1/key-parsers","owner":{"login":"chrismamo1","id":3238755,"avatar_url":"https://avatars.githubusercontent.com/u/3238755?v=3","gravatar_id":"","url":"https://api.github.com/users/chrismamo1","html_url":"https://github.com/chrismamo1","followers_url":"https://api.github.com/users/chrismamo1/followers","following_url":"https://api.github.com/users/chrismamo1/following{/other_user}","gists_url":"https://api.github.com/users/chrismamo1/gists{/gist_id}","starred_url":"https://api.github.com/users/chrismamo1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chrismamo1/subscriptions","organizations_url":"https://api.github.com/users/chrismamo1/orgs","repos_url":"https://api.github.com/users/chrismamo1/repos","events_url":"https://api.github.com/users/chrismamo1/events{/privacy}","received_events_url":"https://api.github.com/users/chrismamo1/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/chrismamo1/key-parsers","description":"OCaml parsers for multiple key formats","fork":true,"url":"https://api.github.com/repos/chrismamo1/key-parsers","forks_url":"https://api.github.com/repos/chrismamo1/key-parsers/forks","keys_url":"https://api.github.com/repos/chrismamo1/key-parsers/keys{/key_id}","collaborators_url":"https://api.github.com/repos/chrismamo1/key-parsers/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/chrismamo1/key-parsers/teams","hooks_url":"https://api.github.com/repos/chrismamo1/key-parsers/hooks","issue_events_url":"https://api.github.com/repos/chrismamo1/key-parsers/issues/events{/number}","events_url":"https://api.github.com/repos/chrismamo1/key-parsers/events","assignees_url":"https://api.github.com/repos/chrismamo1/key-parsers/assignees{/user}","branches_url":"https://api.github.com/repos/chrismamo1/key-parsers/branches{/branch}","tags_url":"https://api.github.com/repos/chrismamo1/key-parsers/tags","blobs_url":"https://api.github.com/repos/chrismamo1/key-parsers/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/chrismamo1/key-parsers/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/chrismamo1/key-parsers/git/refs{/sha}","trees_url":"https://api.github.com/repos/chrismamo1/key-parsers/git/trees{/sha}","statuses_url":"https://api.github.com/repos/chrismamo1/key-parsers/statuses/{sha}","languages_url":"https://api.github.com/repos/chrismamo1/key-parsers/languages","stargazers_url":"https://api.github.com/repos/chrismamo1/key-parsers/stargazers","contributors_url":"https://api.github.com/repos/chrismamo1/key-parsers/contributors","subscribers_url":"https://api.github.com/repos/chrismamo1/key-parsers/subscribers","subscription_url":"https://api.github.com/repos/chrismamo1/key-parsers/subscription","commits_url":"https://api.github.com/repos/chrismamo1/key-parsers/commits{/sha}","git_commits_url":"https://api.github.com/repos/chrismamo1/key-parsers/git/commits{/sha}","comments_url":"https://api.github.com/repos/chrismamo1/key-parsers/comments{/number}","issue_comment_url":"https://api.github.com/repos/chrismamo1/key-parsers/issues/comments{/number}","contents_url":"https://api.github.com/repos/chrismamo1/key-parsers/contents/{+path}","compare_url":"https://api.github.com/repos/chrismamo1/key-parsers/compare/{base}...{head}","merges_url":"https://api.github.com/repos/chrismamo1/key-parsers/merges","archive_url":"https://api.github.com/repos/chrismamo1/key-parsers/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/chrismamo1/key-parsers/downloads","issues_url":"https://api.github.com/repos/chrismamo1/key-parsers/issues{/number}","pulls_url":"https://api.github.com/repos/chrismamo1/key-parsers/pulls{/number}","milestones_url":"https://api.github.com/repos/chrismamo1/key-parsers/milestones{/number}","notifications_url":"https://api.github.com/repos/chrismamo1/key-parsers/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/chrismamo1/key-parsers/labels{/name}","releases_url":"https://api.github.com/repos/chrismamo1/key-parsers/releases{/id}","deployments_url":"https://api.github.com/repos/chrismamo1/key-parsers/deployments","created_at":"2016-08-16T15:32:45Z","updated_at":"2016-08-16T15:32:47Z","pushed_at":"2016-08-22T14:34:14Z","git_url":"git://github.com/chrismamo1/key-parsers.git","ssh_url":"git@github.com:chrismamo1/key-parsers.git","clone_url":"https://github.com/chrismamo1/key-parsers.git","svn_url":"https://github.com/chrismamo1/key-parsers","homepage":null,"size":68,"stargazers_count":0,"watchers_count":0,"language":"OCaml","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":"cryptosense:master","ref":"master","sha":"f91b3cf8d07569ec5c2a9c5eb52b7d59da1cb8ea","user":{"login":"cryptosense","id":4948867,"avatar_url":"https://avatars.githubusercontent.com/u/4948867?v=3","gravatar_id":"","url":"https://api.github.com/users/cryptosense","html_url":"https://github.com/cryptosense","followers_url":"https://api.github.com/users/cryptosense/followers","following_url":"https://api.github.com/users/cryptosense/following{/other_user}","gists_url":"https://api.github.com/users/cryptosense/gists{/gist_id}","starred_url":"https://api.github.com/users/cryptosense/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cryptosense/subscriptions","organizations_url":"https://api.github.com/users/cryptosense/orgs","repos_url":"https://api.github.com/users/cryptosense/repos","events_url":"https://api.github.com/users/cryptosense/events{/privacy}","received_events_url":"https://api.github.com/users/cryptosense/received_events","type":"Organization","site_admin":false},"repo":{"id":45904114,"name":"key-parsers","full_name":"cryptosense/key-parsers","owner":{"login":"cryptosense","id":4948867,"avatar_url":"https://avatars.githubusercontent.com/u/4948867?v=3","gravatar_id":"","url":"https://api.github.com/users/cryptosense","html_url":"https://github.com/cryptosense","followers_url":"https://api.github.com/users/cryptosense/followers","following_url":"https://api.github.com/users/cryptosense/following{/other_user}","gists_url":"https://api.github.com/users/cryptosense/gists{/gist_id}","starred_url":"https://api.github.com/users/cryptosense/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cryptosense/subscriptions","organizations_url":"https://api.github.com/users/cryptosense/orgs","repos_url":"https://api.github.com/users/cryptosense/repos","events_url":"https://api.github.com/users/cryptosense/events{/privacy}","received_events_url":"https://api.github.com/users/cryptosense/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/cryptosense/key-parsers","description":"OCaml parsers for multiple key formats","fork":false,"url":"https://api.github.com/repos/cryptosense/key-parsers","forks_url":"https://api.github.com/repos/cryptosense/key-parsers/forks","keys_url":"https://api.github.com/repos/cryptosense/key-parsers/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cryptosense/key-parsers/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cryptosense/key-parsers/teams","hooks_url":"https://api.github.com/repos/cryptosense/key-parsers/hooks","issue_events_url":"https://api.github.com/repos/cryptosense/key-parsers/issues/events{/number}","events_url":"https://api.github.com/repos/cryptosense/key-parsers/events","assignees_url":"https://api.github.com/repos/cryptosense/key-parsers/assignees{/user}","branches_url":"https://api.github.com/repos/cryptosense/key-parsers/branches{/branch}","tags_url":"https://api.github.com/repos/cryptosense/key-parsers/tags","blobs_url":"https://api.github.com/repos/cryptosense/key-parsers/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cryptosense/key-parsers/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cryptosense/key-parsers/git/refs{/sha}","trees_url":"https://api.github.com/repos/cryptosense/key-parsers/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cryptosense/key-parsers/statuses/{sha}","languages_url":"https://api.github.com/repos/cryptosense/key-parsers/languages","stargazers_url":"https://api.github.com/repos/cryptosense/key-parsers/stargazers","contributors_url":"https://api.github.com/repos/cryptosense/key-parsers/contributors","subscribers_url":"https://api.github.com/repos/cryptosense/key-parsers/subscribers","subscription_url":"https://api.github.com/repos/cryptosense/key-parsers/subscription","commits_url":"https://api.github.com/repos/cryptosense/key-parsers/commits{/sha}","git_commits_url":"https://api.github.com/repos/cryptosense/key-parsers/git/commits{/sha}","comments_url":"https://api.github.com/repos/cryptosense/key-parsers/comments{/number}","issue_comment_url":"https://api.github.com/repos/cryptosense/key-parsers/issues/comments{/number}","contents_url":"https://api.github.com/repos/cryptosense/key-parsers/contents/{+path}","compare_url":"https://api.github.com/repos/cryptosense/key-parsers/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cryptosense/key-parsers/merges","archive_url":"https://api.github.com/repos/cryptosense/key-parsers/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cryptosense/key-parsers/downloads","issues_url":"https://api.github.com/repos/cryptosense/key-parsers/issues{/number}","pulls_url":"https://api.github.com/repos/cryptosense/key-parsers/pulls{/number}","milestones_url":"https://api.github.com/repos/cryptosense/key-parsers/milestones{/number}","notifications_url":"https://api.github.com/repos/cryptosense/key-parsers/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cryptosense/key-parsers/labels{/name}","releases_url":"https://api.github.com/repos/cryptosense/key-parsers/releases{/id}","deployments_url":"https://api.github.com/repos/cryptosense/key-parsers/deployments","created_at":"2015-11-10T10:15:39Z","updated_at":"2016-08-16T17:11:31Z","pushed_at":"2016-08-22T14:34:14Z","git_url":"git://github.com/cryptosense/key-parsers.git","ssh_url":"git@github.com:cryptosense/key-parsers.git","clone_url":"https://github.com/cryptosense/key-parsers.git","svn_url":"https://github.com/cryptosense/key-parsers","homepage":null,"size":52,"stargazers_count":6,"watchers_count":6,"language":"OCaml","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":4,"forks":2,"open_issues":4,"watchers":6,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/cryptosense/key-parsers/pulls/13"},"html":{"href":"https://github.com/cryptosense/key-parsers/pull/13"},"issue":{"href":"https://api.github.com/repos/cryptosense/key-parsers/issues/13"},"comments":{"href":"https://api.github.com/repos/cryptosense/key-parsers/issues/13/comments"},"review_comments":{"href":"https://api.github.com/repos/cryptosense/key-parsers/pulls/13/comments"},"review_comment":{"href":"https://api.github.com/repos/cryptosense/key-parsers/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/cryptosense/key-parsers/pulls/13/commits"},"statuses":{"href":"https://api.github.com/repos/cryptosense/key-parsers/statuses/87a68b7b2754af92d2763e8946bc06cc22153dee"}}}}
{"actor":{"display_login":"emillon"}}