Commits

John Clizbe  committed f187022

Fixes for machine-readable indices.

Key expiration times are now read from self-signatures on the key's UIDs. (KF)
In addition, instead of 8-digit key IDs, index entries now return the most
specific key ID possible: 16-digit key ID for V3 keys, and the full fingerprint
for V4 keys. (JPC)

  • Participants
  • Parent commits f11212b

Comments (0)

Files changed (6)

+Development trunk
+  - Fixes for machine-readable indices. Key expiration times are now read
+    from self-signatures on the key's UIDs. In addition, instead of 8-digit
+    key IDs, index entries now return the most specific key ID possible:
+    16-digit key ID for V3 keys, and the full fingerprint for V4 keys.
+
 1.1.4
   - Fix X-HKP-Results-Count so that limit=0 returns no results, but include
     the header, to let a client poll for how many results exist, without
 let enforced_filters = ["yminsky.dedup"]
 
 let version_tuple = (__VERSION__)
-let version_suffix = "" (* + for development branch *)
+let version_suffix = "+" (* + for development branch *)
 let compatible_version_tuple = (0,1,5)
 let version =
   let (maj_version,min_version,release) = version_tuple in
   sprintf "uid:%s:%s:%s:"
     uid_string (time_to_string ctime) (time_to_string exptime)
 
+let get_key_expiration_from_uid keyid sigs =
+  let sigs = get_self_sigs keyid sigs in
+  let times = List.map ~f:ParsePGP.get_key_exptimes sigs in
+  let (ctime,exptime) =
+    List.fold_left ~init:(None,None) ~f:(fun (cmax,emax) (cr,ex) ->
+      if cr > cmax then (cr, ex) else (cmax, emax)) times in
+  (ctime,exptime)
+
+let key_expiration_from_uids keyid pk_ctime uids =
+ let expir = List.map ~f:(fun (uid,sigs) ->
+      match uid.packet_type with
+          User_ID_Packet -> get_key_expiration_from_uid keyid sigs
+        | _ -> (None, None)
+      ) uids in
+  let (ctime, exptime) =
+     List.fold_left ~init:(None,None) ~f:(fun (cmax,emax) (cr,ex) ->
+       if cr > cmax then (cr, ex) else (cmax, emax)) expir
+  in
+  match exptime with
+   | Some x -> Int64.add x pk_ctime
+   | None -> Int64.zero
+
 (** number of seconds in a day *)
 let daysecs = Int64.of_int (60 * 60 * 24)
 
 let key_to_lines key =
   let full_keyid = Fingerprint.keyid_from_key ~short:false key in
-  let keyid = Fingerprint.keyid_to_string ~short:true full_keyid in
+  let keyid = Fingerprint.keyid_to_string ~short:false full_keyid in
+  let fpr =  Utils.hexstring (Fingerprint.fp_from_key key) in
   let pkey = KeyMerge.key_to_pkey key in
   let key_packet = pkey.KeyMerge.key in
   let pki = ParsePGP.parse_pubkey_info key_packet in
     | Some days -> sprintf "%Ld"
         (Int64.add pki.pk_ctime (Int64.mul daysecs (Int64.of_int days)))
   in
+  let key_expiry = key_expiration_from_uids full_keyid pki.pk_ctime uids
+  in
+    let key_expiry_string = if Int64.to_int key_expiry = 0
+      then exp_string else sprintf "%Ld" key_expiry
+  in
   let key_line = sprintf "pub:%s:%d:%d:%Ld:%s:%s"
-                   keyid
+  (* Since it is not possible to calculate the key ID from a V3 fingerprint, *)
+  (* return the 16-digit key ID for V3 keys.                                 *)
+                  (match String.length fpr with
+                     | 32 -> keyid
+                     |  _ -> fpr )
                    pki.pk_alg
                    pki.pk_keylen
                    pki.pk_ctime
-                   exp_string
+                   key_expiry_string
                    (if (Index.is_revoked key) then "r" else "")
   in
   let uid_lines =
   in
   key_line::uid_lines
 
-
 let keys_to_lines keys =
   let first = sprintf "info:%d:%d" mr_version (List.length keys) in
   let keylines = List.concat (List.map ~f:key_to_lines keys) in
 
 let ssp_ctime_id = 2
 let ssp_exptime_id = 3
+let ssp_keyexptime_id = 9
 
 let int32_of_string s =
   let cin = new Channel.string_in_channel s 0 in
   let cin = new Channel.string_in_channel s 0 in
   cin#read_int64_size (String.length s)
 
+let get_key_exptimes sign = match sign with
+  | V3sig sign ->
+      (Some sign.v3s_ctime, None)
+  | V4sig sign ->
+      let hashed_subpackets = sign.v4s_hashed_subpackets in
+      let (ctime,exptime_delta) =
+        List.fold_left hashed_subpackets ~init:(None,None)
+          ~f:(fun (ctime,exptime) ssp ->
+                if ssp.ssp_type = ssp_ctime_id && ssp.ssp_length = 4 then
+                  (Some (int64_of_string ssp.ssp_body),exptime)
+                else if ssp.ssp_type = ssp_keyexptime_id && ssp.ssp_length = 4 then
+                  (ctime,Some (int64_of_string ssp.ssp_body))
+                else
+                  (ctime,exptime)
+             )
+      in
+      match (ctime,exptime_delta) with
+        | (Some x,None) -> (Some x,None)
+        | (None,_) -> (None,None)
+        | (Some x,Some y) -> (Some x,Some y)
+
+
 let get_times sign = match sign with
   | V3sig sign ->
       (Some sign.v3s_ctime, None)

File parsePGP.mli

 val int32_of_string : string -> int32
 val int64_of_string : string -> int64
 val get_times : Packet.signature -> int64 option * int64 option
+val get_key_exptimes : Packet.signature -> int64 option * int64 option
   printf "SKS version %s%s\n"
     Common.version Common.version_suffix;
 	
-  printf "Compiled with Ocaml version %s and BDB version %s\n" 
+  printf "Compiled with Ocaml version %s and BDB version %s\n"
       Sys.ocaml_version bdb_version;
-  
+
   printf "This SKS version has a minimum compatibility \
          requirement for recon of SKS %s\n"
       Common.compatible_version_string;