@ file : Jvm Name (" Secrets Manager ") Ċ Ċ package Ġcom . keeper security . secrets Manager . core Ċ Ċ import Ġkotlinx . serialization . Experimental Serialization Api Ċ import Ġkotlinx . serialization . Serializable Ċ import Ġkotlinx . serialization . decode FromString Ċ import Ġkotlinx . serialization . encode ToString Ċ import Ġkotlinx . serialization . json . Json Ċ import Ġkotlinx . serialization . json . JsonObject Ċ import Ġkotlinx . serialization . json . json Primitive Ċ import Ġjava . net . Http URLConnection . HTTP _ OK Ċ import Ġjava . net . URL Ċ import Ġjava . security . Key Management Exception Ċ import Ġjava . security . NoSuch AlgorithmException Ċ import Ġjava . security . Secure Random Ċ import Ġjava . security . cert . X 5 0 9 Certificate Ċ import Ġjava . time . Instant Ċ import Ġjava . util .* Ċ import Ġjava . util . jar . Manifest Ċ import Ġjavax . net . ssl .* Ċ Ċ const Ġval ĠKEY _ HOSTNAME Ġ= Ġ" hostname " Ġ// Ġbase Ġurl Ġfor Ġthe ĠSec rets ĠManager Ġservice Ċ const Ġval ĠKEY _ SERVER _ PUB IC _ KEY _ ID Ġ= Ġ" server PublicKey Id " Ċ const Ġval ĠKEY _ CLIENT _ ID Ġ= Ġ" clientId " Ċ const Ġval ĠKEY _ CLIENT _ KEY Ġ= Ġ" client Key " Ġ// ĠThe Ġkey Ġthat Ġis Ġused Ġto Ġidentify Ġthe Ġclient Ġbefore Ġpublic Ġkey Ċ const Ġval ĠKEY _ APP _ KEY Ġ= Ġ" app Key " Ġ// ĠThe Ġapplication Ġkey Ġwith Ġwhich Ġall Ġsecrets Ġare Ġencrypted Ċ const Ġval ĠKEY _ OWNER _ PUBLIC _ KEY Ġ= Ġ" app Owner PublicKey " Ġ// ĠThe Ġapplication Ġowner Ġpublic Ġkey , Ġto Ġcreate Ġrecords Ċ const Ġval ĠKEY _ PRIVATE _ KEY Ġ= Ġ" privateKey " Ġ// ĠThe Ġclient 's Ġprivate Ġkey Ċ const Ġval ĠKEY _ PUBLIC _ KEY Ġ= Ġ" publicKey " Ġ// ĠThe Ġclient 's Ġpublic Ġkey Ċ Ċ private Ġconst Ġval ĠCLIENT _ ID _ HASH _ TAG Ġ= Ġ" KE E PER _ SE CRE TS _ MANAGER _ CLIENT _ ID " Ġ// ĠTag Ġfor Ġhashing Ġthe Ġclient Ġkey Ġto Ġclient Ġid Ċ Ċ interface ĠKey Value Storage Ġ{ ĊĠĠĠ Ġfun ĠgetString ( key : ĠString ): ĠString ? ĊĠĠĠ Ġfun Ġsave String ( key : ĠString , Ġvalue : ĠString ) ĊĠĠĠ Ġfun Ġget Bytes ( key : ĠString ): ĠByteArray ? ĊĠĠĠ Ġfun Ġsave Bytes ( key : ĠString , Ġvalue : ĠByteArray ) ĊĠĠĠ Ġfun Ġdelete ( key : ĠString ) Ċ } Ċ Ċ data Ġclass ĠSec rets Manager Options Ġ@ Jvm Over loads Ġconstructor ( ĊĠĠĠ Ġval Ġstorage : ĠKey Value Storage , ĊĠĠĠ Ġval Ġquery Function : ĠQuery Function ? Ġ= Ġnull , ĊĠĠĠ Ġval Ġallow Un verified Certificate : ĠBoolean Ġ= Ġfalse Ċ ) Ċ Ċ type alias ĠQuery Function Ġ= Ġ( url : ĠString , Ġtransmission Key : ĠTrans mission Key , Ġpayload : ĠEn crypted Payload ) Ġ-> ĠK eeper HttpResponse Ċ Ċ data Ġclass ĠTrans mission Key ( var Ġpublic KeyId : ĠInt , Ġvar Ġkey : ĠByteArray , Ġval Ġencrypted Key : ĠByteArray ) Ċ data Ġclass ĠK eeper HttpResponse ( val ĠstatusCode : ĠInt , Ġval Ġdata : ĠByteArray ) Ċ Ċ @ Serializable Ċ data Ġclass ĠK eeper Error ( val Ġkey _ id : ĠInt , Ġval Ġerror : ĠString ) Ċ Ċ @ Serializable Ċ private Ġdata Ġclass ĠGet Payload ( ĊĠĠĠ Ġval Ġclient Version : ĠString , ĊĠĠĠ Ġval ĠclientId : ĠString , ĊĠĠĠ Ġvar ĠpublicKey : ĠString ? Ġ= Ġnull , ĊĠĠĠ Ġvar Ġrequested Records : ĠList < String >? Ġ= Ġnull Ċ ) Ċ Ċ @ Serializable Ċ private Ġdata Ġclass ĠUpdate Payload ( ĊĠĠĠ Ġval Ġclient Version : ĠString , ĊĠĠĠ Ġval ĠclientId : ĠString , ĊĠĠĠ Ġval Ġrecord Uid : ĠString , ĊĠĠĠ Ġval Ġdata : ĠString , ĊĠĠĠ Ġval Ġrevision : ĠLong ? Ġ= Ġnull Ċ ) Ċ Ċ @ Serializable Ċ private Ġdata Ġclass ĠCreate Payload ( ĊĠĠĠ Ġval Ġclient Version : ĠString , ĊĠĠĠ Ġval ĠclientId : ĠString , ĊĠĠĠ Ġval Ġrecord Uid : ĠString , ĊĠĠĠ Ġval Ġrecord Key : ĠString , ĊĠĠĠ Ġval Ġfolder Uid : ĠString , ĊĠĠĠ Ġval Ġfolder Key : ĠString , ĊĠĠĠ Ġval Ġdata : ĠString , Ċ ) Ċ Ċ @ Serializable Ċ private Ġdata Ġclass ĠFile Upload Payload ( ĊĠĠĠ Ġval Ġclient Version : ĠString , ĊĠĠĠ Ġval ĠclientId : ĠString , ĊĠĠĠ Ġval Ġfile Record Uid : ĠString , ĊĠĠĠ Ġval Ġfile Record Key : ĠString , ĊĠĠĠ Ġval Ġfile Record Data : ĠString , ĊĠĠĠ Ġval Ġowner Record Uid : ĠString , ĊĠĠĠ Ġval Ġowner Record Data : ĠString , ĊĠĠĠ Ġval Ġlink Key : ĠString , ĊĠĠĠ Ġval ĠfileSize : ĠInt , Ġ// Ġwe Ġwill Ġnot Ġallow Ġupload Ġsize Ġ> Ġ 2 GB Ġdue Ġto Ġmemory Ġconstraints Ċ ) Ċ Ċ data Ġclass ĠEn crypted Payload ( val Ġpayload : ĠByteArray , Ġval Ġsignature : ĠByteArray ) Ċ Ċ private Ġdata Ġclass ĠFile Upload Payload And File ( val Ġpayload : ĠFile Upload Payload , Ġval Ġencrypted File : ĠByteArray ) Ċ Ċ @ Serializable Ċ private Ġdata Ġclass ĠSec rets Manager Response Folder ( ĊĠĠĠ Ġval Ġfolder Uid : ĠString , ĊĠĠĠ Ġval Ġfolder Key : ĠString , ĊĠĠĠ Ġval Ġrecords : ĠList < Secrets Manager Response Record > Ċ ) Ċ Ċ @ Serializable Ċ private Ġdata Ġclass ĠSec rets Manager Response Record ( ĊĠĠĠ Ġval Ġrecord Uid : ĠString , ĊĠĠĠ Ġval Ġrecord Key : ĠString , ĊĠĠĠ Ġval Ġdata : ĠString , ĊĠĠĠ Ġval Ġrevision : ĠLong ? Ġ= Ġnull , ĊĠĠĠ Ġval Ġis Editable : ĠBoolean , ĊĠĠĠ Ġval Ġfiles : ĠList < Secrets Manager Response File >? Ċ ) Ċ Ċ @ Serializable Ċ private Ġdata Ġclass ĠSec rets Manager Response File ( ĊĠĠĠ Ġval Ġfile Uid : ĠString , ĊĠĠĠ Ġval Ġfile Key : ĠString , ĊĠĠĠ Ġval Ġdata : ĠString , ĊĠĠĠ Ġval Ġurl : ĠString , ĊĠĠĠ Ġval Ġthumbnail Url : ĠString ? Ċ ) Ċ Ċ @ Serializable Ċ private Ġdata Ġclass ĠSec rets Manager Response ( ĊĠĠĠ Ġval Ġapp Data : ĠString ? Ġ= Ġnull , ĊĠĠĠ Ġval Ġencrypted App Key : ĠString ?, ĊĠĠĠ Ġval Ġapp Owner PublicKey : ĠString ? Ġ= Ġnull , ĊĠĠĠ Ġval Ġfolders : ĠList < Secrets Manager Response Folder > ?, ĊĠĠĠ Ġval Ġrecords : ĠList < Secrets Manager Response Record > ?, ĊĠĠĠ Ġval Ġexpires On : ĠLong ? Ġ= Ġnull , ĊĠĠĠ Ġval Ġwarnings : ĠList < String >? Ġ= Ġnull Ċ ) Ċ Ċ @ Serializable Ċ private Ġdata Ġclass ĠSec rets Manager Add File Response ( ĊĠĠĠ Ġval Ġurl : ĠString , ĊĠĠĠ Ġval Ġparameters : ĠString , ĊĠĠĠ Ġval Ġsuccess StatusCode : ĠInt Ċ ) Ċ Ċ data Ġclass ĠK eeper Secrets ( val Ġapp Data : ĠApp Data , Ġval Ġrecords : ĠList < Keeper Record >, Ġval Ġexpires On : ĠInstant ? Ġ= Ġnull , Ġval Ġwarnings : ĠList < String >? Ġ= Ġnull ) Ġ{ ĊĠĠĠ Ġfun Ġget Record By Uid ( record Uid : ĠString ): ĠK eeper Record ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġrecords . find Ġ{ Ġit . record Uid Ġ== Ġrecord Uid Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Secrets By Title ( record Title : ĠString ): ĠList < Keeper Record > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġrecords . filter Ġ{ Ġit . data . title Ġ== Ġrecord Title Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Secret By Title ( record Title : ĠString ): ĠK eeper Record ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġrecords . find Ġ{ Ġit . data . title Ġ== Ġrecord Title Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ @ Serializable Ċ data Ġclass ĠApp Data ( val Ġtitle : ĠString , Ġval Ġtype : ĠString ) Ċ Ċ data Ġclass ĠK eeper Record ( ĊĠĠĠ Ġval Ġrecord Key : ĠByteArray , ĊĠĠĠ Ġval Ġrecord Uid : ĠString , ĊĠĠĠ Ġvar Ġfolder Uid : ĠString ? Ġ= Ġnull , ĊĠĠĠ Ġvar Ġfolder Key : ĠByteArray ? Ġ= Ġnull , ĊĠĠĠ Ġval Ġdata : ĠK eeper Record Data , ĊĠĠĠ Ġval Ġrevision : ĠLong ? Ġ= Ġ 0 , ĊĠĠĠ Ġval Ġfiles : ĠList < Keeper File >? Ġ= Ġnull Ċ ) Ġ{ ĊĠĠĠ Ġfun Ġget Password (): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpassword Field Ġ= Ġdata . getField < Password >() Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( password Field . value . size Ġ> Ġ 0 ) Ġpassword Field . value [ 0 ] Ġelse Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Title (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġdata . title ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun ĠgetType (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġdata . type ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġupdate Password ( new Password : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpassword Field Ġ= Ġdata . getField < Password >() Ġ?: Ġthrow ĠException (" Password Ġfield Ġis Ġnot Ġpresent Ġon Ġthe Ġrecord Ġ$ record Uid ") ĊĊĠĠĠĠĠĠĠ Ġif Ġ( password Field . value . size Ġ== Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpassword Field . value . add ( new Password ) ĊĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpassword Field . value [ 0 ] Ġ= Ġnew Password ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun ĠgetFile ByName ( fileName : ĠString ): ĠK eeper File ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġfiles ?. find Ġ{ Ġit . data . name Ġ== ĠfileName Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun ĠgetFile By Uid ( file Uid : ĠString ): ĠK eeper File ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġfiles ?. find Ġ{ Ġit . file Uid Ġ== Ġfile Uid Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ data Ġclass ĠK eeper File ( ĊĠĠĠ Ġval Ġfile Key : ĠByteArray , ĊĠĠĠ Ġval Ġfile Uid : ĠString , ĊĠĠĠ Ġval Ġdata : ĠK eeper File Data , ĊĠĠĠ Ġval Ġurl : ĠString , ĊĠĠĠ Ġval Ġthumbnail Url : ĠString ? Ċ ) Ċ Ċ data Ġclass ĠK eeper FileUpload ( ĊĠĠĠ Ġval Ġname : ĠString , ĊĠĠĠ Ġval Ġtitle : ĠString , ĊĠĠĠ Ġval Ġtype : ĠString ?, ĊĠĠĠ Ġval Ġdata : ĠByteArray Ċ ) Ċ Ċ @ Jvm Over loads Ċ fun Ġinitialize Storage ( storage : ĠKey Value Storage , Ġone Time Token : ĠString , Ġhost Name : ĠString ? Ġ= Ġnull ) Ġ{ ĊĠĠĠ Ġval Ġtoken Parts Ġ= Ġone Time Token . split (': ') ĊĠĠĠ Ġval Ġhost : ĠString ĊĠĠĠ Ġval Ġclient Key : ĠString ĊĠĠĠ Ġif Ġ( token Parts . size Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġhost Ġ= Ġhost Name Ġ?: Ġthrow ĠException (" The Ġhostname Ġmust Ġbe Ġpresent Ġin Ġthe Ġtoken Ġor Ġas Ġa Ġparameter ") ĊĠĠĠĠĠĠĠ Ġclient Key Ġ= Ġone Time Token ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġhost Ġ= Ġwhen Ġ( token Parts [ 0 ]. uppercase ( Locale . getDefault ())) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" US " Ġ-> Ġ" keeper security . com " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" EU " Ġ-> Ġ" keeper security . eu " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" AU " Ġ-> Ġ" keeper security . com . au " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" GO V " Ġ-> Ġ" gov cloud . keeper security . us " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġtoken Parts [ 0 ] ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġclient Key Ġ= Ġtoken Parts [ 1 ] ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġclient Key Bytes Ġ= Ġweb Safe 6 4 ToBytes ( client Key ) ĊĠĠĠ Ġval Ġclient Key Hash Ġ= Ġhash ( client Key Bytes , ĠCLIENT _ ID _ HASH _ TAG ) ĊĠĠĠ Ġval ĠclientId Ġ= Ġbytes To Base 6 4 ( client Key Hash ) ĊĠĠĠ Ġval Ġexisting ClientId Ġ= Ġstorage . getString ( KEY _ CLIENT _ ID ) ĊĠĠĠ Ġif Ġ( existing ClientId Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( clientId Ġ== Ġexisting ClientId ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠĠ Ġ// Ġthe Ġstorage Ġis Ġalready Ġinitialized ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġthrow ĠException (" The Ġstorage Ġis Ġalready Ġinitialized Ġwith Ġa Ġdifferent Ġclient ĠId Ġ(${ existing ClientId }) ") ĊĠĠĠ Ġ} ĊĠĠĠ Ġstorage . save String ( KEY _ HOSTNAME , Ġhost ) ĊĠĠĠ Ġstorage . save String ( KEY _ CLIENT _ ID , ĠclientId ) ĊĠĠĠ Ġstorage . save Bytes ( KEY _ CLIENT _ KEY , Ġclient Key Bytes ) ĊĠĠĠ Ġval Ġkey Pair Ġ= Ġgenerate KeyPair () ĊĠĠĠ Ġstorage . save Bytes ( KEY _ PRIVATE _ KEY , Ġkey Pair . private . encoded ) Ġ// Ġprivate Ġkey Ġis Ġstored Ġin ĠD ER , Ġto Ġbe Ġcompatible Ġwith Ġother ĠSDK 's ĊĠĠĠ Ġstorage . save Bytes ( KEY _ PUBLIC _ KEY , Ġextract Public Raw ( key Pair . public )) Ġ// Ġpublic Ġkey Ġstored Ġraw Ċ } Ċ Ċ internal Ġobject ĠManifest Loader Ġ{ ĊĠĠĠ Ġinternal Ġval Ġversion : ĠString ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġclazz Ġ= Ġjava Class ĊĠĠĠĠĠĠĠ Ġval Ġclass Path : ĠString Ġ= Ġclazz . getResource ( clazz . simple Name . toString () Ġ+ Ġ". class ") !!. toString () ĊĠĠĠĠĠĠĠ Ġval Ġlib Path End Ġ= Ġclass Path . lastIndexOf (" !") ĊĠĠĠĠĠĠĠ Ġval ĠfilePath Ġ= Ġif Ġ( lib Path End Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlib Path Ġ= Ġclass Path . substring ( 0 , Ġlib Path End ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ lib Path !/ META - INF / MAN IFEST . MF " ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ Ġ// Ġwe Ġmight Ġbe Ġtesting ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġbuild Path Core Idx Ġ= Ġclass Path . lastIndexOf (" build / classes ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( build Path Core Idx Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuild Path Core Idx Ġ= Ġclass Path . lastIndexOf (" out / production / classes ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuild Path Ġ= Ġclass Path . substring ( 0 , Ġbuild Path Core Idx ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ build Path } build / tmp / jar / MAN IFEST . MF " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġmanifest Ġ= ĠManifest ( URL ( filePath ). open Stream ()) ĊĠĠĠĠĠĠĠ Ġversion Ġ= Ġmanifest . main Attributes . getValue (" Implementation - Version ") ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġto Keeper App Client String ( version : ĠString ): ĠString Ġ{ ĊĠĠĠ Ġreturn Ġ" mj ${ version . replace ("- SNAPSHOT ", Ġ"") }" Ċ } Ċ Ċ @ Experimental Serialization Api Ċ @ Jvm Over loads Ċ fun Ġget Secrets ( options : ĠSec rets Manager Options , Ġrecords Filter : ĠList < String > Ġ= Ġempty List ()): ĠK eeper Secrets Ġ{ ĊĠĠĠ Ġval Ġ( secrets , Ġjust Bound ) Ġ= Ġfetch And Decrypt Secrets ( options , Ġrecords Filter ) ĊĠĠĠ Ġif Ġ( just Bound ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfetch And Decrypt Secrets ( options , Ġrecords Filter ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ( e ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġsecrets Ċ } Ċ Ċ @ Experimental Serialization Api Ċ fun Ġupdate Secret ( options : ĠSec rets Manager Options , Ġrecord : ĠK eeper Record ) Ġ{ ĊĠĠĠ Ġval Ġpayload Ġ= Ġprepare Update Payload ( options . storage , Ġrecord ) ĊĠĠĠ Ġpost Query ( options , Ġ" update _ secret ", Ġpayload ) Ċ } Ċ Ċ @ Experimental Serialization Api Ċ @ Jvm Over loads Ċ fun Ġcreate Secret ( options : ĠSec rets Manager Options , Ġfolder Uid : ĠString , Ġrecord Data : ĠK eeper Record Data , Ġsecrets : ĠK eeper Secrets Ġ= Ġget Secrets ( options )): ĠString Ġ{ ĊĠĠĠ Ġval Ġpayload Ġ= Ġprepare Create Payload ( options . storage , Ġfolder Uid , Ġrecord Data , Ġsecrets ) ĊĠĠĠ Ġpost Query ( options , Ġ" create _ secret ", Ġpayload ) ĊĠĠĠ Ġreturn Ġpayload . record Uid Ċ } Ċ Ċ @ Experimental Serialization Api Ċ fun Ġupload File ( options : ĠSec rets Manager Options , Ġowner Record : ĠK eeper Record , Ġfile : ĠK eeper FileUpload ): ĠString Ġ{ ĊĠĠĠ Ġval Ġpayload And File Ġ= Ġprepare FileUpload Payload ( options . storage , Ġowner Record , Ġfile ) ĊĠĠĠ Ġval Ġresponse Data Ġ= Ġpost Query ( options , Ġ" add _ file ", Ġpayload And File . payload ) ĊĠĠĠ Ġval Ġresponse Ġ= Ġnon Strict Json . decode FromString < Secrets Manager Add File Response >( bytes ToString ( response Data )) ĊĠĠĠ Ġval Ġupload Result Ġ= Ġupload File ( response . url , Ġresponse . parameters , Ġpayload And File . encrypted File ) ĊĠĠĠ Ġif Ġ( upload Result . statusCode Ġ!= Ġresponse . success StatusCode ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠException (" Upload Ġfailed Ġ(${ bytes ToString ( upload Result . data )} ), Ġcode Ġ${ upload Result . statusCode }") ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġpayload And File . payload . file Record Uid Ċ } Ċ Ċ fun Ġdownload File ( file : ĠK eeper File ): ĠByteArray Ġ{ ĊĠĠĠ Ġreturn Ġdownload File ( file , Ġfile . url ) Ċ } Ċ Ċ fun Ġdownload Thumbnail ( file : ĠK eeper File ): ĠByteArray Ġ{ ĊĠĠĠ Ġif Ġ( file . thumbnail Url Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠException (" Thumbnail Ġdoes Ġnot Ġexist Ġfor Ġthe Ġfile Ġ${ file . file Uid }") ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġdownload File ( file , Ġfile . thumbnail Url ) Ċ } Ċ Ċ private Ġfun Ġdownload File ( file : ĠK eeper File , Ġurl : ĠString ): ĠByteArray Ġ{ ĊĠĠĠ Ġwith ( URL ( url ). open Connection () Ġas ĠHttp s URLConnection ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrequest Method Ġ= Ġ" GET " ĊĠĠĠĠĠĠĠ Ġval ĠstatusCode Ġ= Ġresponse Code ĊĠĠĠĠĠĠĠ Ġval Ġdata Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror Stream Ġ!= Ġnull Ġ-> Ġerror Stream . read Bytes () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠinputStream . read Bytes () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( statusCode Ġ!= ĠHTTP _ OK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠException ( String ( data )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġdecrypt ( data , Ġfile . file Key ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġupload File ( url : ĠString , Ġparameters : ĠString , Ġfile Data : ĠByteArray ): ĠK eeper HttpResponse Ġ{ ĊĠĠĠ Ġvar ĠstatusCode : ĠInt ĊĠĠĠ Ġvar Ġdata : ĠByteArray ĊĠĠĠ Ġval Ġboundary Ġ= ĠString . format (" ---------- % x ", ĠInstant . now (). epoch Second ) ĊĠĠĠ Ġval Ġboundary Bytes : ĠByteArray Ġ= Ġstring ToBytes ("\ r \ n -- $ boundary ") ĊĠĠĠ Ġval Ġparam Json Ġ= ĠJson . parse ToJson Element ( parameters ) Ġas ĠJsonObject ĊĠĠĠ Ġwith ( URL ( url ). open Connection () Ġas ĠHttp s URLConnection ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrequest Method Ġ= Ġ" POST " ĊĠĠĠĠĠĠĠ Ġuse Caches Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġdo Input Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġdo Output Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġset Request Property (" Content - Type ", Ġ" multipart / form - data ; Ġboundary =$ boundary ") ĊĠĠĠĠĠĠĠ Ġwith ( output Stream ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( param Ġin Ġparam Json . entries ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( boundary Bytes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( string ToBytes ("\ r \ n Content - Disposition : Ġform - data ; Ġname =\" ${ param . key } \"\ r \ n \ r \ n ${ param . value . json Primitive . content } ")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( boundary Bytes ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( string ToBytes ("\ r \ n Content - Disposition : Ġform - data ; Ġname =\" file \"\ r \ n Content - Type : Ġapplication / octet - stream \ r \ n \ r \ n ")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( file Data ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( boundary Bytes ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( string ToBytes ("-- \ r \ n ")) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠstatusCode Ġ= Ġresponse Code ĊĠĠĠĠĠĠĠ Ġdata Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror Stream Ġ!= Ġnull Ġ-> Ġerror Stream . read Bytes () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠinputStream . read Bytes () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn ĠK eeper HttpResponse ( statusCode , Ġdata ) Ċ } Ċ Ċ @ Experimental Serialization Api Ċ private Ġfun Ġfetch And Decrypt Secrets ( ĊĠĠĠ Ġoptions : ĠSec rets Manager Options , ĊĠĠĠ Ġrecords Filter : ĠList < String > Ċ ): ĠPair < Keeper Secrets , ĠBoolean > Ġ{ ĊĠĠĠ Ġval Ġstorage Ġ= Ġoptions . storage ĊĠĠĠ Ġval Ġpayload Ġ= Ġprepare Get Payload ( storage , Ġrecords Filter ) ĊĠĠĠ Ġval Ġresponse Data Ġ= Ġpost Query ( options , Ġ" get _ secret ", Ġpayload ) ĊĠĠĠ Ġval Ġjson String Ġ= Ġbytes ToString ( response Data ) ĊĠĠĠ Ġval Ġresponse Ġ= Ġnon Strict Json . decode FromString < Secrets Manager Response >( json String ) ĊĠĠĠ Ġvar Ġjust Bound Ġ= Ġfalse ĊĠĠĠ Ġval Ġapp Key : ĠByteArray ĊĠĠĠ Ġif Ġ( response . encrypted App Key Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġjust Bound Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġval Ġclient Key Ġ= Ġstorage . getBytes ( KEY _ CLIENT _ KEY ) Ġ?: Ġthrow ĠException (" Client Ġkey Ġis Ġmissing Ġfrom Ġthe Ġstorage ") ĊĠĠĠĠĠĠĠ Ġapp Key Ġ= Ġdecrypt ( response . encrypted App Key , Ġclient Key ) ĊĠĠĠĠĠĠĠ Ġstorage . save Bytes ( KEY _ APP _ KEY , Ġapp Key ) ĊĠĠĠĠĠĠĠ Ġstorage . delete ( KEY _ CLIENT _ KEY ) ĊĠĠĠĠĠĠĠ Ġstorage . delete ( KEY _ PUBLIC _ KEY ) ĊĠĠĠĠĠĠĠ Ġresponse . app Owner PublicKey ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstorage . save String ( KEY _ OWNER _ PUBLIC _ KEY , Ġit ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġapp Key Ġ= Ġstorage . getBytes ( KEY _ APP _ KEY ) Ġ?: Ġthrow ĠException (" App Ġkey Ġis Ġmissing Ġfrom Ġthe Ġstorage ") ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġrecords : ĠMutable List < Keeper Record > Ġ= Ġmutable ListOf () ĊĠĠĠ Ġif Ġ( response . records Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġresponse . records . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrecord Key Ġ= Ġdecrypt ( it . record Key , Ġapp Key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdecrypted Record Ġ= Ġdecrypt Record ( it , Ġrecord Key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrecords . add ( de crypted Record ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġif Ġ( response . folders Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġresponse . folders . forEach Ġ{ Ġfolder Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfolder Key Ġ= Ġdecrypt ( folder . folder Key , Ġapp Key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfolder . records . forEach Ġ{ Ġrecord Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrecord Key Ġ= Ġdecrypt ( record . record Key , Ġfolder Key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdecrypted Record Ġ= Ġdecrypt Record ( record , Ġrecord Key ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdecrypted Record . folder Uid Ġ= Ġfolder . folder Uid ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdecrypted Record . folder Key Ġ= Ġfolder Key ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrecords . add ( de crypted Record ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġapp Data Ġ= Ġif Ġ( response . app Data Ġ== Ġnull ) ĊĠĠĠĠĠĠĠ ĠApp Data ("", Ġ"") Ġelse ĊĠĠĠĠĠĠĠ Ġnon Strict Json . decode FromString ( bytes ToString ( decrypt ( web Safe 6 4 ToBytes ( response . app Data ), Ġapp Key ))) ĊĠĠĠ Ġval Ġwarnings Ġ= Ġif Ġ( response . warnings Ġ== Ġnull Ġ|| Ġresponse . warnings . isEmpty ()) Ġnull Ġelse Ġresponse . warnings ĊĠĠĠ Ġval Ġsecrets Ġ= ĠK eeper Secrets ( ĊĠĠĠĠĠĠĠ Ġapp Data , ĊĠĠĠĠĠĠĠ Ġrecords , ĊĠĠĠĠĠĠĠ Ġif Ġ( response . expires On Ġ!= Ġnull Ġ&& Ġresponse . expires On Ġ> Ġ 0 ) ĠInstant . of Epoch Milli ( response . expires On ) Ġelse Ġnull , ĊĠĠĠĠĠĠĠ Ġwarnings ) ĊĠĠĠ Ġreturn ĠPair ( secrets , Ġjust Bound ) Ċ } Ċ Ċ @ Experimental Serialization Api Ċ private Ġfun Ġdecrypt Record ( record : ĠSec rets Manager Response Record , Ġrecord Key : ĠByteArray ): ĠK eeper Record Ġ{ ĊĠĠĠ Ġval Ġdecrypted Record Ġ= Ġdecrypt ( record . data , Ġrecord Key ) ĊĊĠĠĠ Ġval Ġfiles : ĠMutable List < Keeper File > Ġ= Ġmutable ListOf () ĊĊĠĠĠ Ġif Ġ( record . files Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrecord . files . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Key Ġ= Ġdecrypt ( it . file Key , Ġrecord Key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdecrypted File Ġ= Ġdecrypt ( it . data , Ġfile Key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfiles . add ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠK eeper File ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile Key , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . file Uid , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠJson . decode FromString ( bytes ToString ( de crypted File )), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . url , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . thumbnail Url ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn ĠK eeper Record ( record Key , Ġrecord . record Uid , Ġnull , Ġnull , ĠJson . decode FromString ( bytes ToString ( de crypted Record )), Ġrecord . revision , Ġfiles ) Ċ } Ċ Ċ private Ġfun Ġprepare Get Payload ( ĊĠĠĠ Ġstorage : ĠKey Value Storage , ĊĠĠĠ Ġrecords Filter : ĠList < String > Ċ ): ĠGet Payload Ġ{ ĊĠĠĠ Ġval ĠclientId Ġ= Ġstorage . getString ( KEY _ CLIENT _ ID ) Ġ?: Ġthrow ĠException (" Client ĠId Ġis Ġmissing Ġfrom Ġthe Ġconfiguration ") ĊĠĠĠ Ġval Ġpayload Ġ= ĠGet Payload ( ĊĠĠĠĠĠĠĠ Ġto Keeper App Client String ( Manifest Loader . version ), ĊĠĠĠĠĠĠĠ ĠclientId , ĊĠĠĠĠĠĠĠ Ġnull , ĊĠĠĠĠĠĠĠ Ġnull ĊĠĠĠ Ġ) ĊĠĠĠ Ġval Ġapp Key Ġ= Ġstorage . getBytes ( KEY _ APP _ KEY ) ĊĠĠĠ Ġif Ġ( app Key Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠpublicKey Ġ= Ġstorage . getBytes ( KEY _ PUBLIC _ KEY ) Ġ?: Ġthrow ĠException (" Public Ġkey Ġis Ġmissing Ġfrom Ġthe Ġstorage ") ĊĠĠĠĠĠĠĠ Ġpayload . publicKey Ġ= Ġbytes To Base 6 4 ( publicKey ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġif Ġ( records Filter . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġpayload . requested Records Ġ= Ġrecords Filter ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġpayload Ċ } Ċ Ċ @ Experimental Serialization Api Ċ private Ġfun Ġprepare Update Payload ( ĊĠĠĠ Ġstorage : ĠKey Value Storage , ĊĠĠĠ Ġrecord : ĠK eeper Record Ċ ): ĠUpdate Payload Ġ{ ĊĠĠĠ Ġval ĠclientId Ġ= Ġstorage . getString ( KEY _ CLIENT _ ID ) Ġ?: Ġthrow ĠException (" Client ĠId Ġis Ġmissing Ġfrom Ġthe Ġconfiguration ") ĊĠĠĠ Ġval Ġrecord Bytes Ġ= Ġstring ToBytes ( Json . encode ToString ( record . data )) ĊĠĠĠ Ġval Ġencrypted Record Ġ= Ġencrypt ( record Bytes , Ġrecord . record Key ) ĊĠĠĠ Ġreturn ĠUpdate Payload ( to Keeper App Client String ( Manifest Loader . version ), ĠclientId , Ġrecord . record Uid , Ġweb Safe 6 4 From Bytes ( encrypted Record ), Ġrecord . revision ) Ċ } Ċ Ċ @ Experimental Serialization Api Ċ private Ġfun Ġprepare Create Payload ( ĊĠĠĠ Ġstorage : ĠKey Value Storage , ĊĠĠĠ Ġfolder Uid : ĠString , ĊĠĠĠ Ġrecord Data : ĠK eeper Record Data , ĊĠĠĠ Ġsecrets : ĠK eeper Secrets Ċ ): ĠCreate Payload Ġ{ ĊĠĠĠ Ġval ĠclientId Ġ= Ġstorage . getString ( KEY _ CLIENT _ ID ) Ġ?: Ġthrow ĠException (" Client ĠId Ġis Ġmissing Ġfrom Ġthe Ġconfiguration ") ĊĠĠĠ Ġval Ġowner PublicKey Ġ= Ġstorage . getBytes ( KEY _ OWNER _ PUBLIC _ KEY ) Ġ?: Ġthrow ĠException (" Application Ġowner Ġpublic Ġkey Ġis Ġmissing Ġfrom Ġthe Ġconfiguration ") ĊĠĠĠ Ġval Ġrecord From Folder Ġ= Ġsecrets . records . find Ġ{ Ġit . folder Uid Ġ== Ġfolder Uid Ġ} ĊĠĠĠ Ġif Ġ( record From Folder ?. folder Key Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠException (" Unable Ġto Ġcreate Ġrecord Ġ- Ġfolder Ġkey Ġfor Ġ$ folder Uid Ġnot Ġfound ") ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġrecord Bytes Ġ= Ġstring ToBytes ( Json . encode ToString ( record Data )) ĊĠĠĠ Ġval Ġrecord Key Ġ= ĠgetRandom Bytes ( 3 2 ) ĊĠĠĠ Ġval Ġrecord Uid Ġ= ĠgetRandom Bytes ( 1 6 ) ĊĠĠĠ Ġval Ġencrypted Record Ġ= Ġencrypt ( record Bytes , Ġrecord Key ) ĊĠĠĠ Ġval Ġencrypted Record Key Ġ= Ġpublic Encrypt ( record Key , Ġowner PublicKey ) ĊĠĠĠ Ġval Ġencrypted Folder Key Ġ= Ġencrypt ( record Key , Ġrecord From Folder . folder Key !! ) ĊĠĠĠ Ġreturn ĠCreate Payload ( to Keeper App Client String ( Manifest Loader . version ), ĠclientId , ĊĠĠĠĠĠĠĠ Ġweb Safe 6 4 From Bytes ( record Uid ), ĊĠĠĠĠĠĠĠ Ġbytes To Base 6 4 ( encrypted Record Key ), ĊĠĠĠĠĠĠĠ Ġfolder Uid , ĊĠĠĠĠĠĠĠ Ġbytes To Base 6 4 ( encrypted Folder Key ), ĊĠĠĠĠĠĠĠ Ġweb Safe 6 4 From Bytes ( encrypted Record )) Ċ } Ċ Ċ @ Experimental Serialization Api Ċ private Ġfun Ġprepare FileUpload Payload ( ĊĠĠĠ Ġstorage : ĠKey Value Storage , ĊĠĠĠ Ġowner Record : ĠK eeper Record , ĊĠĠĠ Ġfile : ĠK eeper FileUpload Ċ ): ĠFile Upload Payload And File Ġ{ ĊĠĠĠ Ġval ĠclientId Ġ= Ġstorage . getString ( KEY _ CLIENT _ ID ) Ġ?: Ġthrow ĠException (" Client ĠId Ġis Ġmissing Ġfrom Ġthe Ġconfiguration ") ĊĠĠĠ Ġval Ġowner PublicKey Ġ= Ġstorage . getBytes ( KEY _ OWNER _ PUBLIC _ KEY ) Ġ?: Ġthrow ĠException (" Application Ġowner Ġpublic Ġkey Ġis Ġmissing Ġfrom Ġthe Ġconfiguration ") ĊĊĠĠĠ Ġval Ġfile Data Ġ= ĠK eeper File Data ( ĊĠĠĠĠĠĠĠ Ġfile . title , ĊĠĠĠĠĠĠĠ Ġfile . name , ĊĠĠĠĠĠĠĠ Ġfile . type , ĊĠĠĠĠĠĠĠ Ġfile . data . size . to Long (), ĊĠĠĠĠĠĠĠ ĠInstant . now (). to Epoch Milli () ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġval Ġfile Record Bytes Ġ= Ġstring ToBytes ( Json . encode ToString ( file Data )) ĊĠĠĠ Ġval Ġfile Record Key Ġ= ĠgetRandom Bytes ( 3 2 ) ĊĠĠĠ Ġval Ġfile Record Uid Ġ= Ġweb Safe 6 4 From Bytes ( getRandom Bytes ( 1 6 )) ĊĠĠĠ Ġval Ġencrypted File Record Ġ= Ġencrypt ( file Record Bytes , Ġfile Record Key ) ĊĠĠĠ Ġval Ġencrypted File Record Key Ġ= Ġpublic Encrypt ( file Record Key , Ġowner PublicKey ) ĊĠĠĠ Ġval Ġencrypted Link Key Ġ= Ġencrypt ( file Record Key , Ġowner Record . record Key ) ĊĠĠĠ Ġval Ġencrypted File Data Ġ= Ġencrypt ( file . data , Ġfile Record Key ) ĊĊĠĠĠ Ġval Ġfile Ref Ġ= Ġowner Record . data . getField < File Ref >() ĊĠĠĠ Ġif Ġ( file Ref Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġowner Record . data . fields . add ( File Ref ( value Ġ= Ġmutable ListOf ( file Record Uid ))) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġfile Ref . value . add ( file Record Uid ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġowner Record Bytes Ġ= Ġstring ToBytes ( Json . encode ToString ( owner Record . data )) ĊĠĠĠ Ġval Ġencrypted Owner Record Ġ= Ġencrypt ( owner Record Bytes , Ġowner Record . record Key ) ĊĊĠĠĠ Ġreturn ĠFile Upload Payload And File ( ĊĠĠĠĠĠĠĠ ĠFile Upload Payload ( to Keeper App Client String ( Manifest Loader . version ), ĠclientId , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile Record Uid , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbytes To Base 6 4 ( encrypted File Record Key ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġweb Safe 6 4 From Bytes ( encrypted File Record ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġowner Record . record Uid , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġweb Safe 6 4 From Bytes ( encrypted Owner Record ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbytes To Base 6 4 ( encrypted Link Key ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġencrypted File Data . size ĊĠĠĠĠĠĠĠ Ġ), ĊĠĠĠĠĠĠĠ Ġencrypted File Data ĊĠĠĠ Ġ) Ċ } Ċ Ċ fun Ġcaching Post Function ( url : ĠString , Ġtransmission Key : ĠTrans mission Key , Ġpayload : ĠEn crypted Payload ): ĠK eeper HttpResponse Ġ{ ĊĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġpost Function ( url , Ġtransmission Key , Ġpayload , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġif Ġ( response . statusCode Ġ== ĠHTTP _ OK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsave Cached Value ( transmission Key . key Ġ+ Ġresponse . data ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġresponse ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcached Data Ġ= Ġget Cached Value () ĊĠĠĠĠĠĠĠ Ġval Ġcached Trans mission Key Ġ= Ġcached Data . copyOf Range ( 0 , Ġ 3 2 ) ĊĠĠĠĠĠĠĠ Ġtransmission Key . key Ġ= Ġcached Trans mission Key ĊĠĠĠĠĠĠĠ Ġval Ġdata Ġ= Ġcached Data . copyOf Range ( 3 2 , Ġcached Data . size ) ĊĠĠĠĠĠĠĠ ĠK eeper HttpResponse ( HTTP _ OK , Ġdata ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġpost Function ( ĊĠĠĠ Ġurl : ĠString , ĊĠĠĠ Ġtransmission Key : ĠTrans mission Key , ĊĠĠĠ Ġpayload : ĠEn crypted Payload , ĊĠĠĠ Ġallow Un verified Certificate : ĠBoolean Ċ ): ĠK eeper HttpResponse Ġ{ ĊĠĠĠ Ġvar ĠstatusCode : ĠInt ĊĠĠĠ Ġvar Ġdata : ĠByteArray ĊĠĠĠ Ġwith ( URL ( url ). open Connection () Ġas ĠHttp s URLConnection ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( allow Un verified Certificate ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġssl Socket Factory Ġ= Ġtrust All Socket Factory () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġrequest Method Ġ= Ġ" POST " ĊĠĠĠĠĠĠĠ Ġdo Output Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġset Request Property (" PublicKey Id ", Ġtransmission Key . public KeyId . toString ()) ĊĠĠĠĠĠĠĠ Ġset Request Property (" Trans mission Key ", Ġbytes To Base 6 4 ( transmission Key . encrypted Key )) ĊĠĠĠĠĠĠĠ Ġset Request Property (" Authorization ", Ġ" Signature Ġ${ bytes To Base 6 4 ( payload . signature )} ") ĊĠĠĠĠĠĠĠ ĠoutputStream . write ( payload . payload ) ĊĠĠĠĠĠĠĠ ĠoutputStream . flush () ĊĠĠĠĠĠĠĠ ĠstatusCode Ġ= Ġresponse Code ĊĠĠĠĠĠĠĠ Ġdata Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerror Stream Ġ!= Ġnull Ġ-> Ġerror Stream . read Bytes () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠinputStream . read Bytes () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn ĠK eeper HttpResponse ( statusCode , Ġdata ) Ċ } Ċ Ċ private Ġval Ġnon Strict Json Ġ= ĠJson Ġ{ Ġignore Unknown Keys Ġ= Ġtrue Ġ} Ċ Ċ var Ġkey Id Ġ= Ġ 7 Ċ Ċ @ Suppress (" Spell Checking Inspection ") Ċ private Ġval Ġke eper Public Keys Ġ= ĠlistOf ( ĊĠĠĠ Ġ" BK 9 w 6 TZ F xE 6 n FN b Mf Ip UL Cup 2 a 8 xc 6 w 2 t UT AB jx ny 7 y F mx W 0 d AE o jw C 6 j 6 zb 5 n Tl mb 1 d Ax 8 n wo 3 q F 7 R PY Gm lo RM ", ĊĠĠĠ Ġ" BK n hy 0 ob gl Z JK - ig w th NL dk no S XR r GB - mv FR zy b _ L - DK K ef Wj Y d FD 2 8 8 8 q N 1 RO c zz 4 n 3 ke YS f Kz 9 Ko j 9 0 Z 6 w _ t Q ", ĊĠĠĠ Ġ" B As PQ d Cp L IG Xd WN Ld A wx - 3 J 5 l Nq Ut K ba OM V 5 6 h Uj 8 Vz xE 2 US L Hu HH u KD eno 0 ym Jt - ac x WV 1 x Pl Bf NU Sh h R TR 7 7 g ", ĊĠĠĠ Ġ" BN YI h _ Sv 0 3 n R Z UU J ve E 8 d 2 mx KL IDX v 6 5 4 Ub sha It Hr CJ hd 6 c T 7 pd Z _ X w bd y xA OC WM kB b 9 AZ 4 t 1 X RC s M 8 - wk E BR g ", ĊĠĠĠ Ġ" BA 6 u N fe YS vq ag wu 4 TO Y 6 w FK 4 Jy U 5 C 2 0 0 v J na 0 l H 4 PJ - Sz GV X ej 8 l 9 d E ly Q 5 8 _ lj f Ps 5 Rq 6 z VV X pd De 8 A 7 Y 3 WR hk ", ĊĠĠĠ Ġ" BM j TI l X fo h I 8 TD y ms H xo 0 D q Y ys Cy 7 y Z GJ 8 0 Wh g OB R 4 QU d 6 LB DA 6 -_ 3 1 8 a - j CG W 9 6 zx XK Mm 8 cl DT Kp E 8 w 7 5 KG - FY ", ĊĠĠĠ Ġ" BJ BD U 1 P 1 H 2 1 Iw Id T 2 br Kk P qb QR 0 Zl 0 TI Hf 7 Bz _ OO 9 ja Ng Iw yd Mk xt 4 Gp B mk Y op r Z _ DH UG Or no 2 fa B 7 pm TR 7 H hu I ", ĊĠĠĠ Ġ" BJ FF 8 j - d H 7 p DE w _ U 3 4 7 w 2 CB M 6 x YM 8 Dk 5 f PP A kt j ib - op O qz vv bs ER - WD HM 4 ON CS Bf 9 O _ ob AH z C yy g xm tp kt D ui E ", ĊĠĠĠ Ġ" B DK y WB v L by Z - j M ue OR l 3 Jw J nn Ep Ci Zd N 7 y Uv T 0 v Oy j wp PB CD f 6 zf L 4 RW zv Sk h AA Fn w On i _ 1 t Q Sl 8 df XH b X q Xs Q 8 ", ĊĠĠĠ Ġ" BD Xy ZZ n rl 0 tc 2 jd C 5 I 6 1 Jj wk j K 2 kr 7 ue t 9 t Z jt 8 St Ti J TA QQ mn VO Y B gb t P 0 8 PW Db ecx n H gh x 3 k J 8 QX q 1 XE 6 8 y 8 c ", ĊĠĠĠ Ġ" B FX 6 8 cb 9 7 m 9 _ s we Gd OV av FM 3 j 5 ot 6 g ve g 6 x T 4 Bt G ah f Gh K ib - zd Zy O 9 pw vv 1 c B da 9 ah k S zo 1 BQ 4 NV Xp 9 q Ry q V GU " Ċ ). associate By ({ Ġkey Id ++ Ġ}, Ġ{ Ġweb Safe 6 4 ToBytes ( it ) Ġ}) Ċ Ċ private Ġfun Ġgenerate Trans mission Key ( storage : ĠKey Value Storage ): ĠTrans mission Key Ġ{ ĊĠĠĠ Ġval Ġtransmission Key Ġ= Ġif Ġ( Test Stub s . transmission Key Stub Ready ()) Ġ{ ĊĠĠĠĠĠĠĠ ĠTest Stub s . transmission Key Stub () ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ ĠgetRandom Bytes ( 3 2 ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġkey Number : ĠInt Ġ= Ġstorage . getString ( KEY _ SERVER _ PUB IC _ KEY _ ID )?. toInt () Ġ?: Ġ 7 ĊĠĠĠ Ġval Ġke eper PublicKey Ġ= Ġke eper Public Keys [ key Number ] Ġ?: Ġthrow ĠException (" Key Ġnumber Ġ$ key Number Ġis Ġnot Ġsupported ") ĊĠĠĠ Ġval Ġencrypted Key Ġ= Ġpublic Encrypt ( transmission Key , Ġke eper PublicKey ) ĊĠĠĠ Ġreturn ĠTrans mission Key ( key Number , Ġtransmission Key , Ġencrypted Key ) Ċ } Ċ Ċ @ Experimental Serialization Api Ċ private Ġinline Ġfun Ġ< re ified ĠT > Ġencrypt And Sign Payload ( ĊĠĠĠ Ġstorage : ĠKey Value Storage , ĊĠĠĠ Ġtransmission Key : ĠTrans mission Key , ĊĠĠĠ Ġpayload : ĠT Ċ ): ĠEn crypted Payload Ġ{ ĊĠĠĠ Ġval Ġpayload Bytes Ġ= Ġstring ToBytes ( Json . encode ToString ( payload )) ĊĠĠĠ Ġval Ġencrypted Payload Ġ= Ġencrypt ( payload Bytes , Ġtransmission Key . key ) ĊĠĠĠ Ġval ĠprivateKey Ġ= Ġstorage . getBytes ( KEY _ PRIVATE _ KEY ) Ġ?: Ġthrow ĠException (" Private Ġkey Ġis Ġmissing Ġfrom Ġthe Ġstorage ") ĊĠĠĠ Ġval Ġsignature Base Ġ= Ġtransmission Key . encrypted Key Ġ+ Ġencrypted Payload ĊĠĠĠ Ġval Ġsignature Ġ= Ġsign ( signature Base , ĠprivateKey ) ĊĠĠĠ Ġreturn ĠEn crypted Payload ( encrypted Payload , Ġsignature ) Ċ } Ċ Ċ @ Experimental Serialization Api Ċ private Ġinline Ġfun Ġ< re ified ĠT > Ġpost Query ( ĊĠĠĠ Ġoptions : ĠSec rets Manager Options , ĊĠĠĠ Ġpath : ĠString , ĊĠĠĠ Ġpayload : ĠT Ċ ): ĠByteArray Ġ{ ĊĠĠĠ Ġval Ġhost Name Ġ= Ġoptions . storage . getString ( KEY _ HOSTNAME ) Ġ?: Ġthrow ĠException (" hostname Ġis Ġmissing Ġfrom Ġthe Ġstorage ") ĊĠĠĠ Ġval Ġurl Ġ= Ġ" https ://${ host Name }/ api / rest / sm / v 1 /${ path }" ĊĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtransmission Key Ġ= Ġgenerate Trans mission Key ( options . storage ) ĊĠĠĠĠĠĠĠ Ġval Ġencrypted Payload Ġ= Ġencrypt And Sign Payload ( options . storage , Ġtransmission Key , Ġpayload ) ĊĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġif Ġ( options . query Function Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpost Function ( url , Ġtransmission Key , Ġencrypted Payload , Ġoptions . allow Un verified Certificate ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoptions . query Function . invoke ( url , Ġtransmission Key , Ġencrypted Payload ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( response . statusCode Ġ!= ĠHTTP _ OK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠerrorMessage Ġ= ĠString ( response . data ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġerror Ġ= Ġnon Strict Json . decode FromString < Keeper Error >( errorMessage ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( error . error Ġ== Ġ" key ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoptions . storage . save String ( KEY _ SERVER _ PUB IC _ KEY _ ID , Ġerror . key _ id . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠException ( errorMessage ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( response . data . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresponse . data ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġdecrypt ( response . data , Ġtransmission Key . key ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġtrust All Socket Factory (): ĠSSL Socket Factory Ġ{ ĊĠĠĠ Ġval Ġtrust All Certs : ĠArray < Trust Manager > Ġ= ĠarrayOf ( ĊĠĠĠĠĠĠĠ Ġobject Ġ: ĠX 5 0 9 Trust Manager Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval ĠAccept ed Iss u ers Ġ= ĠarrayOf < X 5 0 9 Certificate >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcheck Client Trusted ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcerts : ĠArray < X 5 0 9 Certificate ?> ?, Ġauth Type : ĠString ? ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġcheck Server Trusted ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcerts : ĠArray < X 5 0 9 Certificate ?> ?, Ġauth Type : ĠString ? ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġget Accepted Iss u ers (): ĠArray < X 5 0 9 Certificate > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠAccept ed Iss u ers ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ) ĊĠĠĠ Ġval Ġssl Context Ġ= ĠSSL Context . getInstance (" TLS ") ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġssl Context . init ( null , Ġtrust All Certs , ĠSecure Random ()) ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠNoSuch AlgorithmException ) Ġ{ ĊĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠKey Management Exception ) Ġ{ ĊĠĠĠĠĠĠĠ Ġe . printStackTrace () ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġssl Context . socket Factory Ċ } Ċ Ċ internal Ġobject ĠTest Stub s Ġ{ ĊĠĠĠ Ġlateinit Ġvar Ġtransmission Key Stub : Ġ() Ġ-> ĠByteArray ĊĊĠĠĠ Ġfun Ġtransmission Key Stub Ready (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġthis :: transmission Key Stub . isInitialized ĊĠĠĠ Ġ} Ċ }