struct ed25519_cert { u8 version IN [1]; u8 cert_type; u32 exp_field; u8 cert_key_type; u8 certified_key[32]; u8 n_extensions; struct ed25519_cert_extension ext[n_extensions]; u8 signature[64]; } const CERTEXT_SIGNED_WITH_KEY = 4; const CERTEXT_FLAG_AFFECTS_VALIDATION = 1; struct ed25519_cert_extension { u16 ext_length; u8 ext_type; u8 ext_flags; union un[ext_type] with length ext_length { CERTEXT_SIGNED_WITH_KEY : u8 signing_key[32]; default: u8 unparsed[]; }; } const LS_IPV4 = 0x00; const LS_IPV6 = 0x01; const LS_LEGACY_ID = 0x02; const LS_ED25519_ID = 0x03; // XXX hs_link_specifier_dup() violates the opaqueness of link_specifier_t by // taking its sizeof(). If we ever want to turn on TRUNNEL_OPAQUE, or // if we ever make link_specifier contain other types, we will // need to refactor that function to do the copy by encoding and decoding the // object. // amended from tor.trunnel struct link_specifier { u8 ls_type; u8 ls_len; union un[ls_type] with length ls_len { LS_IPV4: u32 ipv4_addr; u16 ipv4_port; LS_IPV6: u8 ipv6_addr[16]; u16 ipv6_port; LS_LEGACY_ID: u8 legacy_id[20]; LS_ED25519_ID: u8 ed25519_id[32]; default: u8 unrecognized[]; }; } struct link_specifier_list { u8 n_spec; struct link_specifier spec[n_spec]; } struct extend1_cell_body { u32 ipv4addr; u16 port; u8 onionskin[186]; u8 identity[20]; } struct create2_cell_body { u16 handshake_type; u16 handshake_len; u8 handshake_data[handshake_len]; } struct extend2_cell_body { u8 n_spec; struct link_specifier ls[n_spec]; struct create2_cell_body create2; }