123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275typet=Unsigned.ULong.t[@@derivingord]letequal=Pervasives.(=)letshow=Unsigned.ULong.to_stringletppfmtn=Format.pp_print_stringfmt(shown)let(!)x=Unsigned.ULong.of_string(Int64.to_stringx)letempty=Unsigned.ULong.zeroletlogical_or=Unsigned.ULong.logorlet(||)=logical_orletlogical_and=Unsigned.ULong.logandletget~(flags:t)~(flag:t):bool=not(equal(logical_andflagsflag)empty)typedomain=|Info_domain|Slot_info_domain|Token_info_domain|Session_info_domain|Mechanism_info_domain|Initialize_domain|Wait_for_slot_domain|OTP_signature_info_domain|Any_domain(* CK_SLOT_INFO *)let_CKF_TOKEN_PRESENT=!0x00000001Llet_CKF_REMOVABLE_DEVICE=!0x00000002Llet_CKF_HW_SLOT=!0x00000004L(* CK_TOKEN_INFO *)let_CKF_RNG=!0x00000001Llet_CKF_WRITE_PROTECTED=!0x00000002Llet_CKF_LOGIN_REQUIRED=!0x00000004Llet_CKF_USER_PIN_INITIALIZED=!0x00000008Llet_CKF_RESTORE_KEY_NOT_NEEDED=!0x00000020Llet_CKF_CLOCK_ON_TOKEN=!0x00000040Llet_CKF_PROTECTED_AUTHENTICATION_PATH=!0x00000100Llet_CKF_DUAL_CRYPTO_OPERATIONS=!0x00000200Llet_CKF_TOKEN_INITIALIZED=!0x00000400Llet_CKF_SECONDARY_AUTHENTICATION=!0x00000800Llet_CKF_USER_PIN_COUNT_LOW=!0x00010000Llet_CKF_USER_PIN_FINAL_TRY=!0x00020000Llet_CKF_USER_PIN_LOCKED=!0x00040000Llet_CKF_USER_PIN_TO_BE_CHANGED=!0x00080000Llet_CKF_SO_PIN_COUNT_LOW=!0x00100000Llet_CKF_SO_PIN_FINAL_TRY=!0x00200000Llet_CKF_SO_PIN_LOCKED=!0x00400000Llet_CKF_SO_PIN_TO_BE_CHANGED=!0x00800000L(* CK_SESSION_INFO *)let_CKF_RW_SESSION=!0x00000002Llet_CKF_SERIAL_SESSION=!0x00000004L(* The following flag is actually a bit which is present in CKA values
which consists in an array of attributes. *)let_CKF_ARRAY_ATTRIBUTE=!0x40000000L(* CK_MECHANISM_INFO *)let_CKF_HW=!0x00000001Llet_CKF_ENCRYPT=!0x00000100Llet_CKF_DECRYPT=!0x00000200Llet_CKF_DIGEST=!0x00000400Llet_CKF_SIGN=!0x00000800Llet_CKF_SIGN_RECOVER=!0x00001000Llet_CKF_VERIFY=!0x00002000Llet_CKF_VERIFY_RECOVER=!0x00004000Llet_CKF_GENERATE=!0x00008000Llet_CKF_GENERATE_KEY_PAIR=!0x00010000Llet_CKF_WRAP=!0x00020000Llet_CKF_UNWRAP=!0x00040000Llet_CKF_DERIVE=!0x00080000Llet_CKF_EC_F_P=!0x00100000Llet_CKF_EC_F_2M=!0x00200000Llet_CKF_EC_ECPARAMETERS=!0x00400000Llet_CKF_EC_NAMEDCURVE=!0x00800000Llet_CKF_EC_UNCOMPRESS=!0x01000000Llet_CKF_EC_COMPRESS=!0x02000000Llet_CKF_EXTENSION=!0x80000000L(* C_Initialize *)let_CKF_LIBRARY_CANT_CREATE_OS_THREADS=!0x00000001Llet_CKF_OS_LOCKING_OK=!0x00000002L(* C_WaitForSlotEvent *)let_CKF_DONT_BLOCK=!0x00000001L(* CK_OTP_SIGNATURE_INFO *)let_CKF_NEXT_OTP=!0x00000001Llet_CKF_EXCLUDE_TIME=!0x00000002Llet_CKF_EXCLUDE_COUNTER=!0x00000004Llet_CKF_EXCLUDE_CHALLENGE=!0x00000008Llet_CKF_EXCLUDE_PIN=!0x00000010Llet_CKF_USER_FRIENDLY_OTP=!0x00000020Lletto_string=Unsigned.ULong.to_stringletof_string=Unsigned.ULong.of_stringletto_json?pretty(flags:t)=matchprettywith|None->`String(to_stringflags)|Somepretty->`Assoc["value",`String(to_stringflags);"string",`String(prettyflags)](* for now, just use assoc lists for the mappings as there are not many *)letpretty_string_mappings=(* There are no flags for CK_INFO in v2.20 *)letinfo=[]inletslot_info=[_CKF_TOKEN_PRESENT,"CKF_TOKEN_PRESENT";_CKF_REMOVABLE_DEVICE,"CKF_REMOVABLE_DEVICE";_CKF_HW_SLOT,"CKF_HW_SLOT";]inlettoken_info=[_CKF_RNG,"CKF_RNG";_CKF_WRITE_PROTECTED,"CKF_WRITE_PROTECTED";_CKF_LOGIN_REQUIRED,"CKF_LOGIN_REQUIRED";_CKF_USER_PIN_INITIALIZED,"CKF_USER_PIN_INITIALIZED";_CKF_RESTORE_KEY_NOT_NEEDED,"CKF_RESTORE_KEY_NOT_NEEDED";_CKF_CLOCK_ON_TOKEN,"CKF_CLOCK_ON_TOKEN";_CKF_PROTECTED_AUTHENTICATION_PATH,"CKF_PROTECTED_AUTHENTICATION_PATH";_CKF_DUAL_CRYPTO_OPERATIONS,"CKF_DUAL_CRYPTO_OPERATIONS";_CKF_TOKEN_INITIALIZED,"CKF_TOKEN_INITIALIZED";_CKF_SECONDARY_AUTHENTICATION,"CKF_SECONDARY_AUTHENTICATION";_CKF_USER_PIN_COUNT_LOW,"CKF_USER_PIN_COUNT_LOW";_CKF_USER_PIN_FINAL_TRY,"CKF_USER_PIN_FINAL_TRY";_CKF_USER_PIN_LOCKED,"CKF_USER_PIN_LOCKED";_CKF_USER_PIN_TO_BE_CHANGED,"CKF_USER_PIN_TO_BE_CHANGED";_CKF_SO_PIN_COUNT_LOW,"CKF_SO_PIN_COUNT_LOW";_CKF_SO_PIN_FINAL_TRY,"CKF_SO_PIN_FINAL_TRY";_CKF_SO_PIN_LOCKED,"CKF_SO_PIN_LOCKED";_CKF_SO_PIN_TO_BE_CHANGED,"CKF_SO_PIN_TO_BE_CHANGED";]inletsession_info=[_CKF_RW_SESSION,"CKF_RW_SESSION";_CKF_SERIAL_SESSION,"CKF_SERIAL_SESSION";]inletany=[_CKF_ARRAY_ATTRIBUTE,"CKF_ARRAY_ATTRIBUTE";]inletmechanism_info=[_CKF_HW,"CKF_HW";_CKF_ENCRYPT,"CKF_ENCRYPT";_CKF_DECRYPT,"CKF_DECRYPT";_CKF_DIGEST,"CKF_DIGEST";_CKF_SIGN,"CKF_SIGN";_CKF_SIGN_RECOVER,"CKF_SIGN_RECOVER";_CKF_VERIFY,"CKF_VERIFY";_CKF_VERIFY_RECOVER,"CKF_VERIFY_RECOVER";_CKF_GENERATE,"CKF_GENERATE";_CKF_GENERATE_KEY_PAIR,"CKF_GENERATE_KEY_PAIR";_CKF_WRAP,"CKF_WRAP";_CKF_UNWRAP,"CKF_UNWRAP";_CKF_DERIVE,"CKF_DERIVE";_CKF_EC_F_P,"CKF_EC_F_P";_CKF_EC_F_2M,"CKF_EC_F_2M";_CKF_EC_ECPARAMETERS,"CKF_EC_ECPARAMETERS";_CKF_EC_NAMEDCURVE,"CKF_EC_NAMEDCURVE";_CKF_EC_UNCOMPRESS,"CKF_EC_UNCOMPRESS";_CKF_EC_COMPRESS,"CKF_EC_COMPRESS";_CKF_EXTENSION,"CKF_EXTENSION";]inletinitialize=[_CKF_LIBRARY_CANT_CREATE_OS_THREADS,"CKF_LIBRARY_CANT_CREATE_OS_THREADS";_CKF_OS_LOCKING_OK,"CKF_OS_LOCKING_OK";]inletwait_for_slot=[_CKF_DONT_BLOCK,"CKF_DONT_BLOCK";]inletotp_signature_info=[_CKF_NEXT_OTP,"CKF_NEXT_OTP";_CKF_EXCLUDE_TIME,"CKF_EXCLUDE_TIME";_CKF_EXCLUDE_COUNTER,"CKF_EXCLUDE_COUNTER";_CKF_EXCLUDE_CHALLENGE,"CKF_EXCLUDE_CHALLENGE";_CKF_EXCLUDE_PIN,"CKF_EXCLUDE_PIN";_CKF_USER_FRIENDLY_OTP,"CKF_USER_FRIENDLY_OTP";]in[Info_domain,info;Slot_info_domain,slot_info;Token_info_domain,token_info;Session_info_domain,session_info;Mechanism_info_domain,mechanism_info;Initialize_domain,initialize;Wait_for_slot_domain,wait_for_slot;OTP_signature_info_domain,otp_signature_info;Any_domain,any;]letflags_of_domaindomain=tryList.assocdomainpretty_string_mappingswithNot_found->[]letsplit_with_stringdomainflags:((t*string)list*t)=letexpected_flags=flags_of_domaindomaininlet(split_flags,remaining)=List.fold_left(fun((expected_flags,remaining_flags)asacc)(flag,str)->ifget~flag~flagsthenletremaining_flags=logical_andremaining_flags(Unsigned.ULong.lognotflag)inletexpected_flags=(flag,str)::expected_flagsinexpected_flags,remaining_flagselseacc)([],flags)expected_flagsin(List.revsplit_flags,remaining)letsplitdomainflags:(tlist*t)=let(flags,remaining)=split_with_stringdomainflagsin(List.mapfstflags,remaining)letto_pretty_stringsdomainflags=let(flags,remaining)=split_with_stringdomainflagsinletflags=List.mapsndflagsinifequalremainingemptythenflagselseflags@[Printf.sprintf"0x%Lx"@@Int64.of_string@@Unsigned.ULong.to_stringremaining]letto_pretty_stringdomainflags=letflags=to_pretty_stringsdomainflagsinmatchflagswith|[]->"(none)"|f->String.concat" | "ftypehas_value={value:Yojson.Safe.json;string:string}[@@derivingof_yojson]letof_yojsonjson=(* We know that [P11_ulong.to_yojson] does not produce [`Assoc]s. *)letactual_json=matchhas_value_of_yojsonjsonwith|Ok{value;_}->value|Error_->jsoninP11_ulong.of_yojsonactual_jsonletto_yojson=to_json?pretty:None