123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303typet=Unsigned.ULong.t[@@derivingord]letequal=Stdlib.(=)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_mappingswith|Not_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_flagsin(expected_flags,remaining_flags)elseacc)([],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.t;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