/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 ĠB ab ylon ĠPart ners ĠLimited Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ* Ċ Ġ* ĠCode Ġderived Ġfrom Ġhttps :// github . com / square / okhttp / Ġand Ċ Ġ* Ġhttps :// github . com / google / con sc rypt / Ċ Ġ*/ Ċ Ċ package Ġcom . babylon . certificate tr ansparency . chain clean er Ċ Ċ import Ġjava . security . cert . X 5 0 9 Certificate Ċ import Ġjava . util . Array Deque Ċ import Ġjavax . net . ssl . SSL Peer Un verified Exception Ċ import Ġjavax . net . ssl . X 5 0 9 Trust Manager Ċ Ċ /** Ċ Ġ* ĠCertificate Ġchain Ġcleaner Ġthat Ġuses Ġ[ X 5 0 9 Trust Manager . get Accepted Iss u ers ] Ġto Ġbuild Ġa Ġtrusted Ġchain , Ġd uplic ating Ġwhat Ġhappens Ġduring Ġa Ċ Ġ* Ġsecure Ġconnection Ġhandshake . Ċ Ġ*/ Ċ internal Ġclass ĠBasic Certificate Chain Clean er ( ĊĠĠĠ Ġtrust Manager : ĠX 5 0 9 Trust Manager Ċ ) Ġ: ĠCertificate Chain Clean er Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġsubject To Ca Certs Ġ= Ġtrust Manager . accepted Iss u ers . groupBy Ġ{ Ġit . subject X 5 0 0 Principal Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturns Ġa Ġcleaned Ġcertificate Ġchain Ġfrom Ġ[ chain ]. ĠAn Ġexception Ġis Ġthrown Ġif Ġa Ġvalid Ġchain Ġcannot Ġbe Ġfound , Ġwhich Ġmay Ġhappen Ġif Ġa ĊĠĠĠĠ Ġ* Ġdifferent Ġ[ X 5 0 9 Trust Manager ] Ġis Ġused Ġto Ġestablish Ġthe Ġsecure Ġconnection . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Suppress (" Long Method ") ĊĠĠĠ Ġ@ Throws ( SSL Peer Un verified Exception :: class ) ĊĠĠĠ Ġoverride Ġfun Ġclean ( chain : ĠList < X 5 0 9 Certificate >, Ġhostname : ĠString ): ĠList < X 5 0 9 Certificate > Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( chain . isEmpty ()) Ġthrow ĠSSL Peer Un verified Exception (" Certificate Ġchain Ġis Ġempty ") ĊĊĠĠĠĠĠĠĠ Ġval Ġqueue Ġ= ĠArray Deque < X 5 0 9 Certificate >( chain ) ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġmutable ListOf < X 5 0 9 Certificate >() ĊĠĠĠĠĠĠĠ Ġresult . add ( queue . remove First ()) ĊĠĠĠĠĠĠĠ Ġvar Ġfound Trusted Certificate Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠ Ġrepeat ( MAX _ SIGN ERS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto Verify Ġ= Ġresult . last () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġthis Ġcert Ġhas Ġbeen Ġsigned Ġby Ġa Ġtrusted Ġcert , Ġuse Ġthat . ĠAdd Ġthe Ġtrusted Ġcertificate Ġto ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthe Ġend Ġof Ġthe Ġchain Ġunless Ġit 's Ġalready Ġpresent . Ġ( That Ġwould Ġhappen Ġif Ġthe Ġfirst ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcertificate Ġin Ġthe Ġchain Ġis Ġitself Ġa Ġself - signed Ġand Ġtrusted ĠCA Ġcertificate .) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfind Trusted Cert By Issuer And Signature ( to Verify )?. also Ġ{ Ġtrusted Cert Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAdd Ġtrusted Ġcert Ġto Ġthe Ġchain Ġunless Ġit Ġis Ġalready Ġthere ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result . size Ġ> Ġ 1 Ġ|| Ġto Verify Ġ!= Ġtrusted Cert ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add ( trusted Cert ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( trusted Cert . is Signed By ( trusted Cert )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSelf - signed Ġcert Ġis Ġa Ġroot ĠCA Ġso Ġwe Ġare Ġat Ġthe Ġend Ġof Ġthe Ġchain ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfound Trusted Certificate Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġlet Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFind Ġthe Ġfirst Ġcertificate Ġin Ġthe Ġchain Ġthat Ġsigns Ġ[ to Verify ]. ĠUsually Ġthe Ġnext Ġelement , Ġbut Ġnot Ġalways ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġqueue . first OrNull Ġ{ Ġsigning Cert Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Verify . is Signed By ( signing Cert ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ?. also Ġ{ Ġsigning Cert Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġqueue . remove ( signing Cert ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add ( signing Cert ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġlet Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNo Ġmatching Ġcert Ġfound Ġso Ġthe Ġend Ġof Ġthe Ġchain Ġis Ġreached . ĠIf Ġany Ġcert Ġin Ġthe Ġchain Ġis Ġtrusted Ġthen Ġreturn Ġthe Ġchain ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( found Trusted Certificate ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNo Ġcertificate Ġis Ġtrusted Ġand Ġwe 've Ġgone Ġthrough Ġthe Ġentire Ġchain Ġso Ġfail ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠSSL Peer Un verified Exception (" Failed Ġto Ġfind Ġa Ġtrusted Ġcert Ġthat Ġsigned Ġ$ to Verify ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġthrow ĠSSL Peer Un verified Exception (" Certificate Ġchain Ġtoo Ġlong : Ġ$ result ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfind Trusted Cert By Issuer And Signature ( cert : ĠX 5 0 9 Certificate ): ĠX 5 0 9 Certificate ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġissuer Ġ= Ġcert . issuer X 5 0 0 Principal ĊĠĠĠĠĠĠĠ Ġreturn Ġsubject To Ca Certs [ issuer ]?. first OrNull Ġ{ Ġcert . is Signed By ( it ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠReturns Ġtrue Ġif Ġ[ this ] Ġis Ġsigned Ġby Ġthe Ġpublic Ġkey Ġof Ġ[ signing Cert ] ĊĠĠĠĠ Ġ* Ġ Ġ@ receiver ĠAn Ġ[ X 5 0 9 Certificate ] ĊĠĠĠĠ Ġ**/ ĊĠĠĠ Ġprivate Ġfun ĠX 5 0 9 Certificate . is Signed By ( signing Cert : ĠX 5 0 9 Certificate ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( issuer DN Ġ!= Ġsigning Cert . subject DN ) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġverify ( signing Cert . publicKey ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ignored : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĠMaximum Ġsign ers Ġin Ġa Ġchain , Ġusing Ġ 9 Ġfor Ġconsistency Ġwith ĠOpenSSL Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMAX _ SIGN ERS Ġ= Ġ 9 ĊĠĠĠ Ġ} Ċ } Ċ