PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /home/.cpanm/work/1729881436.834049/Net-SSLeay-1.94/inc/Test/Net
Viewing File: /home/.cpanm/work/1729881436.834049/Net-SSLeay-1.94/inc/Test/Net/SSLeay.pm
package Test::Net::SSLeay; use 5.008001; use strict; use warnings; use base qw(Exporter); use Carp qw(croak); use Config; use Cwd qw(abs_path); use English qw( $EVAL_ERROR $OSNAME $PERL_VERSION -no_match_vars ); use File::Basename qw(dirname); use File::Spec::Functions qw( abs2rel catfile ); use Test::Builder; use Test::Net::SSLeay::Socket; our $VERSION = '1.94'; our @EXPORT_OK = qw( can_fork can_really_fork can_thread data_file_path dies_like dies_ok doesnt_warn initialise_libssl is_libressl is_openssl is_protocol_usable lives_ok new_ctx protocols tcp_socket warns_like ); my $tester = Test::Builder->new(); my $data_path = catfile( dirname(__FILE__), '..', '..', '..', 't', 'data' ); my $initialised = 0; my %protos = ( 'TLSv1.3' => { constant => \&Net::SSLeay::TLS1_3_VERSION, constant_type => 'version', priority => 6, }, 'TLSv1.2' => { constant => \&Net::SSLeay::TLSv1_2_method, constant_type => 'method', priority => 5, }, 'TLSv1.1' => { constant => \&Net::SSLeay::TLSv1_1_method, constant_type => 'method', priority => 4, }, 'TLSv1' => { constant => \&Net::SSLeay::TLSv1_method, constant_type => 'method', priority => 3, }, 'SSLv3' => { constant => \&Net::SSLeay::SSLv3_method, constant_type => 'method', priority => 2, }, 'SSLv2' => { constant => \&Net::SSLeay::SSLv2_method, constant_type => 'method', priority => 1, }, ); my ( $test_no_warnings, $test_no_warnings_name, @warnings ); END { _test_no_warnings() if $test_no_warnings; } sub _all { my ( $sub, @list ) = @_; for (@list) { $sub->() or return 0; } return 1; } sub _diag { my (%args) = @_; $tester->diag( ' ' x 9, 'got: ', $args{got} ); $tester->diag( ' ' x 4, 'expected: ', $args{expected} ); } sub _libssl_fatal { my ($context) = @_; croak "$context: " . Net::SSLeay::ERR_error_string( Net::SSLeay::ERR_get_error() ); } sub _load_net_ssleay { eval { require Net::SSLeay; 1; } or croak $EVAL_ERROR; return 1; } sub _test_no_warnings { my $got_str = join q{, }, map { qq{'$_'} } @warnings; my $got_type = @warnings == 1 ? 'warning' : 'warnings'; $tester->ok( @warnings == 0, $test_no_warnings_name ) or _diag( got => "$got_type $got_str", expected => 'no warnings', ); } sub import { my ( $class, @imports ) = @_; # Enable strict and warnings in the caller strict->import; warnings->import; # Import common modules into the caller's namespace my $caller = caller; for (qw(Test::More)) { eval "package $caller; use $_; 1;" or croak $EVAL_ERROR; } # Import requested Test::Net::SSLeay symbols into the caller's namespace __PACKAGE__->export_to_level( 1, $class, @imports ); return 1; } sub can_fork { return 1 if can_really_fork(); # Some platforms provide fork emulation using ithreads return 1 if $Config{d_pseudofork}; # d_pseudofork was added in Perl 5.10.0 - this is an approximation for # older Perls if ( ( $OSNAME eq 'Win32' or $OSNAME eq 'NetWare' ) and $Config{useithreads} and $Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/ ) { return 1; } return can_thread(); } sub can_really_fork { return 1 if $Config{d_fork}; return 0; } sub can_thread { return 0 if not $Config{useithreads}; # Threads are broken in Perl 5.10.0 when compiled with GCC 4.8 or above # (see GH #175) if ( $PERL_VERSION == 5.010000 and $Config{ccname} eq 'gcc' and defined $Config{gccversion} # gccversion is sometimes defined for non-GCC compilers (see GH-350); # compilers that are truly GCC are identified with a version number in # gccversion and $Config{gccversion} =~ /^\d+\.\d+/ ) { my ( $gcc_major, $gcc_minor ) = split /[.\s]+/, $Config{gccversion}; return 0 if ( $gcc_major > 4 or ( $gcc_major == 4 and $gcc_minor >= 8 ) ); } # Devel::Cover doesn't (currently) work with threads return 0 if $INC{'Devel/Cover.pm'}; return 1; } sub data_file_path { my ($data_file) = @_; my $abs_path = catfile( abs_path($data_path), $data_file ); my $rel_path = abs2rel($abs_path); croak "$rel_path: data file does not exist" if not -e $abs_path; return $rel_path; } sub dies_like { my ( $sub, $expected, $name ) = @_; my ( $got, $ok ); if ( eval { $sub->(); 1 } ) { $ok = $tester->ok ( 0, $name ); _diag( got => 'subroutine lived', expected => "subroutine died with exception matching $expected", ); } else { $got = $EVAL_ERROR; my $test = $got =~ $expected; $ok = $tester->ok( $test, $name ) or _diag( got => qq{subroutine died with exception '$got'}, expected => "subroutine died with exception matching $expected", ); } $EVAL_ERROR = $got; return $ok; } sub dies_ok { my ( $sub, $name ) = @_; my ( $got, $ok ); if ( eval { $sub->(); 1 } ) { $got = $EVAL_ERROR; $ok = $tester->ok ( 0, $name ); _diag( got => 'subroutine lived', expected => 'subroutine died', ); } else { $got = $EVAL_ERROR; $ok = $tester->ok( 1, $name ); } $EVAL_ERROR = $got; return $ok; } sub doesnt_warn { $test_no_warnings = 1; $test_no_warnings_name = shift; $SIG{__WARN__} = sub { push @warnings, shift }; } sub initialise_libssl { return 1 if $initialised; _load_net_ssleay(); Net::SSLeay::randomize(); # Error strings aren't loaded by default until OpenSSL 1.1.0, but it's safe # to load them unconditionally because these functions are simply no-ops in # later OpenSSL versions Net::SSLeay::load_error_strings(); Net::SSLeay::ERR_load_crypto_strings(); Net::SSLeay::library_init(); # The test suite makes heavy use of SHA-256, but SHA-256 isn't registered by # default in all OpenSSL versions - register it manually when Net::SSLeay is # built against the following OpenSSL versions: # OpenSSL 0.9.8 series < 0.9.8o Net::SSLeay::OpenSSL_add_all_digests() if Net::SSLeay::constant('OPENSSL_VERSION_NUMBER') < 0x009080ff; # OpenSSL 1.0.0 series < 1.0.0a Net::SSLeay::OpenSSL_add_all_digests() if Net::SSLeay::constant('OPENSSL_VERSION_NUMBER') >= 0x10000000 && Net::SSLeay::constant('OPENSSL_VERSION_NUMBER') < 0x1000001f; $initialised = 1; return 1; } sub is_libressl { _load_net_ssleay(); # The most foolproof method of checking whether libssl is provided by # LibreSSL is by checking OPENSSL_VERSION_NUMBER: every version of # LibreSSL identifies itself as OpenSSL 2.0.0, which is a version number # that OpenSSL itself will never use (version 3.0.0 follows 1.1.1) return 0 if Net::SSLeay::constant('OPENSSL_VERSION_NUMBER') != 0x20000000; return 1; } sub is_openssl { _load_net_ssleay(); # "OpenSSL 2.0.0" is actually LibreSSL return 0 if Net::SSLeay::constant('OPENSSL_VERSION_NUMBER') == 0x20000000; return 1; } sub is_protocol_usable { my ($proto) = @_; _load_net_ssleay(); initialise_libssl(); my $proto_data = $protos{$proto}; # If libssl does not support this protocol version, or if it was disabled at # compile-time, the appropriate method for that version will be missing if ( $proto_data->{constant_type} eq 'version' ? !eval { &{ $proto_data->{constant} }; 1 } : !defined &{ $proto_data->{constant} } ) { return 0; } # If libssl was built with support for this protocol version, the only # reliable way to test whether its use is permitted by the security policy # is to attempt to create a connection that uses it - if it is permitted, # the state machine enters the following states: # # SSL_CB_HANDSHAKE_START (ret=1) # SSL_CB_CONNECT_LOOP (ret=1) # SSL_CB_CONNECT_EXIT (ret=-1) # # If it is not permitted, the state machine instead enters the following # states: # # SSL_CB_HANDSHAKE_START (ret=1) # SSL_CB_CONNECT_EXIT (ret=-1) # # Additionally, ERR_get_error() returns the error code 0x14161044, although # this might not necessarily be guaranteed for all libssl versions, so # testing for it may be unreliable my $constant = $proto_data->{constant}->(); my $ctx; if ( $proto_data->{constant_type} eq 'version' ) { $ctx = Net::SSLeay::CTX_new_with_method( Net::SSLeay::TLS_method() ) or _libssl_fatal('Failed to create libssl SSL_CTX object'); Net::SSLeay::CTX_set_min_proto_version( $ctx, $constant ); Net::SSLeay::CTX_set_max_proto_version( $ctx, $constant ); } else { $ctx = Net::SSLeay::CTX_new_with_method($constant) or _libssl_fatal('Failed to create SSL_CTX object'); } my $ssl = Net::SSLeay::new($ctx) or _libssl_fatal('Failed to create SSL structure'); # For the purposes of this test, it isn't necessary to link the SSL # structure to a file descriptor, since no data actually needs to be sent or # received Net::SSLeay::set_fd( $ssl, -1 ) or _libssl_fatal('Failed to set file descriptor for SSL structure'); my @states; Net::SSLeay::CTX_set_info_callback( $ctx, sub { my ( $ssl, $where, $ret, $data ) = @_; push @states, $where; } ); Net::SSLeay::connect($ssl) or _libssl_fatal('Failed to initiate connection'); my $disabled = Net::SSLeay::CB_HANDSHAKE_START() + Net::SSLeay::CB_CONNECT_EXIT(); my $enabled = Net::SSLeay::CB_HANDSHAKE_START() + Net::SSLeay::CB_CONNECT_LOOP() + Net::SSLeay::CB_CONNECT_EXIT(); Net::SSLeay::free($ssl); Net::SSLeay::CTX_free($ctx); my $observed = 0; for my $state (@states) { $observed += $state; } return 0 if $observed == $disabled; return 1 if $observed == $enabled; croak 'Unexpected TLS state machine sequence: ' . join( ', ', @states ); } sub lives_ok { my ( $sub, $name ) = @_; my ( $got, $ok ); if ( !eval { $sub->(); 1 } ) { $got = $EVAL_ERROR; $ok = $tester->ok ( 0, $name ); _diag( got => qq{subroutine died with exception '$got'}, expected => 'subroutine lived', ); } else { $got = $EVAL_ERROR; $ok = $tester->ok( 1, $name ); } $EVAL_ERROR = $got; return $ok; } sub new_ctx { my ( $min_proto, $max_proto ) = @_; my @usable_protos = # Exclude protocol versions not supported by this libssl: grep { is_protocol_usable($_) } # Exclude protocol versions outside the desired range: grep { ( defined $min_proto ? $protos{$_}->{priority} >= $protos{$min_proto}->{priority} : 1 ) && ( defined $max_proto ? $protos{$_}->{priority} <= $protos{$max_proto}->{priority} : 1 ) } protocols(); croak 'Failed to create libssl SSL_CTX object: no usable protocol versions' if !@usable_protos; my $proto = shift @usable_protos; my $constant = $protos{$proto}->{constant}->(); my $ctx; if ( $protos{$proto}->{constant_type} eq 'version' ) { $ctx = Net::SSLeay::CTX_new_with_method( Net::SSLeay::TLS_method() ) or _libssl_fatal('Failed to create libssl SSL_CTX object'); Net::SSLeay::CTX_set_min_proto_version( $ctx, $constant ); Net::SSLeay::CTX_set_max_proto_version( $ctx, $constant ); } else { $ctx = Net::SSLeay::CTX_new_with_method($constant) or _libssl_fatal('Failed to create SSL_CTX object'); } return wantarray ? ( $ctx, $proto ) : $ctx; } sub protocols { return sort { $protos{$b}->{priority} <=> $protos{$a}->{priority} } keys %protos; } sub tcp_socket { return Test::Net::SSLeay::Socket->new( proto => 'tcp' ); } sub warns_like { my ( $sub, $expected, $name ) = @_; my @expected = ref $expected eq 'ARRAY' ? @$expected : ($expected); my @got; local $SIG{__WARN__} = sub { push @got, shift }; $sub->(); $SIG{__WARN__} = 'DEFAULT'; my $test = scalar @got == scalar @expected && _all( sub { $got[$_] =~ $expected[$_] }, 0 .. $#got ); my $ok = $tester->ok( $test, $name ) or do { my $got_str = join q{, }, map { qq{'$_'} } @got; my $expected_str = join q{, }, map { qq{'$_'} } @expected; my $got_plural = @got == 1 ? '' : 's'; my $expected_plural = @expected == 1 ? '' : 's'; _diag( got => "warning$got_plural $got_str", expected => "warning$expected_plural matching $expected_str", ); }; return $ok; } 1; __END__ =head1 NAME Test::Net::SSLeay - Helper module for the Net-SSLeay test suite =head1 VERSION This document describes version 1.94 of Test::Net::SSLeay. =head1 SYNOPSIS In a Net-SSLeay test script: # Optional summary of the purpose of the tests in this script use lib 'inc'; use Net::SSLeay; # if required by the tests use Test::Net::SSLeay qw(initialise_libssl); # import other helper # functions if required # Imports of other modules specific to this test script # Plan tests, or skip them altogether if certain preconditions aren't met if (disqualifying_condition) { plan skip_all => ...; } else { plan tests => ...; } # If this script tests Net::SSLeay functionality: initialise_libssl(); # Perform one or more Test::More-based tests =head1 DESCRIPTION This is a helper module that makes it easier (or, at least, less repetitive) to write test scripts for the Net-SSLeay test suite. For consistency, all test scripts should import this module and follow the preamble structure given in L</SYNOPSIS>. Importing this module has the following effects on the caller, regardless of whether any exports are requested: =over 4 =item * C<strict> and C<warnings> are enabled; =item * L<Test::More|Test::More>, the test framework used by the Net-SSLeay test suite, is imported. =back No symbols are exported by default. If desired, individual helper functions may be imported into the caller's namespace by specifying their name in the import list; see L</"HELPER FUNCTIONS"> for a list of available helper functions. =head1 HELPER FUNCTIONS =head2 can_fork if (can_fork()) { # Run tests that rely on a working fork() implementation } Returns true if this system natively supports the C<fork()> system call, or if Perl can emulate C<fork()> on this system using interpreter-level threads. Otherwise, returns false. =head2 can_really_fork if (can_really_fork()) { # Run tests that rely on a native fork() implementation } Returns true if this system natively supports the C<fork()> system call, or false if not. =head2 can_thread if (can_thread()) { # Run tests that rely on working threads support } Returns true if reliable interpreter-level threads support is available in this Perl, or false if not. =head2 data_file_path my $cert_path = data_file_path('wildcard-cert.cert.pem'); my $key_path = data_file_path('wildcard-cert.key.pem'); Returns the relative path to a given file in the test suite data directory (C<t/local/>). Dies if the file does not exist. =head2 dies_like dies_like( sub { die 'This subroutine always dies' }, qr/always/, 'A test that always passes' ); Similar to L<C<throws_ok> in Test::Exception|Test::Exception/throws_ok>: performs a L<Test::Builder> test that passes if a given subroutine dies with an exception string that matches a given pattern, or fails if the subroutine does not die or dies with an exception string that does not match the given pattern. This function preserves the value of C<$@> set by the given subroutine, so (for example) other tests can be performed on the value of C<$@> afterwards. =head2 dies_ok dies_ok( sub { my $x = 1 }, 'A test that always fails' ); Similar to L<C<dies_ok> in Test::Exception|Test::Exception/dies_ok>: performs a L<Test::Builder> test that passes if a given subroutine dies, or fails if it does not. This function preserves the value of C<$@> set by the given subroutine, so (for example) other tests can be performed on the value of C<$@> afterwards. =head2 doesnt_warn doesnt_warn('Test script outputs no unexpected warnings'); Offers similar functionality to L<Test::NoWarnings>: performs a L<Test::Builder> test at the end of the test script that passes if the test script executes from this point onwards without emitting any unexpected warnings, or fails if warnings are emitted before the test script ends. Warnings omitted by subroutines that are executed as part of a L</warns_like> test are not considered to be unexpected (even if the L</warns_like> test fails), and will therefore not cause this test to fail. =head2 initialise_libssl initialise_libssl(); # Run tests that call Net::SSLeay functions Initialises libssl (and libcrypto) by seeding the pseudorandom number generator, loading error strings, and registering the default TLS ciphers and digest functions. All digest functions are explicitly registered when Net::SSLeay is built against a libssl version that does not register SHA-256 by default, since SHA-256 is used heavily in the test suite PKI. libssl will only be initialised the first time this function is called, so it is safe for it to be called multiple times in the same test script. =head2 is_libressl if (is_libressl()) { # Run LibreSSL-specific tests } Returns true if libssl is provided by LibreSSL, or false if not. =head2 is_openssl if (is_openssl()) { # Run OpenSSL-specific tests } Returns true if libssl is provided by OpenSSL, or false if not. =head2 is_protocol_usable if ( is_protocol_usable('TLSv1.1') ) { # Run TLSv1.1 tests } Returns true if libssl can communicate using the given SSL/TLS protocol version (represented as a string of the format returned by L</protocols>), or false if not. Note that the availability of a particular SSL/TLS protocol version may vary based on the version of OpenSSL or LibreSSL in use, the options chosen when it was compiled (e.g., OpenSSL will not support SSLv3 if it was built with C<no-ssl3>), or run-time configuration (e.g., the use of TLSv1.0 will be forbidden if the OpenSSL configuration sets the default security level to 3 or higher; see L<SSL_CTX_set_security_level(3)>). =head2 lives_ok lives_ok( sub { die 'Whoops' }, 'A test that always fails' ); Similar to L<C<lives_ok> in Test::Exception|Test::Exception/lives_ok>: performs a L<Test::Builder> test that passes if a given subroutine executes without dying, or fails if it dies during execution. This function preserves the value of C<$@> set by the given subroutine, so (for example) other tests can be performed on the value of C<$@> afterwards. =head2 new_ctx my $ctx = new_ctx(); # $ctx is an SSL_CTX that uses the highest available protocol version my ( $ctx, $version ) = new_ctx( 'TLSv1', 'TLSv1.2' ); # $ctx is an SSL_CTX that uses the highest available protocol version # between TLSv1 and TLSv1.2 inclusive; $version contains the protocol # version chosen Creates a libssl SSL_CTX object that uses the most recent SSL/TLS protocol version supported by libssl, optionally bounded by the given minimum and maximum protocol versions (represented as strings of the format returned by L</protocols>). If called in scalar context, returns the SSL_CTX object that was created. If called in array context, returns the SSL_CTX object and a string containing the protocol version used by the SSL_CTX object. Dies if libssl does not support any of the protocol versions in the given range, or if an SSL_CTX object that uses the chosen protocol version could not be created. =head2 protocols my @protos = protocols(); Returns an array containing strings that describe the SSL/TLS protocol versions supported by L<Net::SSLeay>: C<'TLSv1.3'>, C<'TLSv1.2'>, C<'TLSv1.1'>, C<'TLSv1'>, C<'SSLv3'>, and C<'SSLv2'>. The protocol versions are sorted in reverse order of age (i.e. in the order shown here). Note that it may not be possible to communicate using some of these protocol versions, depending on how libssl was compiled and is configured. These strings can be given as parameters to L</is_protocol_usable> to discover whether the protocol version is actually usable by libssl. =head2 tcp_socket my $server = tcp_socket(); # Accept connection from client: my $sock_in = $server->accept(); # Create connection to server: my $sock_out = $server->connect(); Creates a TCP server socket that listens on localhost on an arbitrarily-chosen free port. Convenience methods are provided for accepting, establishing and closing connections. Returns a L<Test::Net::SSLeay::Socket|Test::Net::SSLeay::Socket> object. Dies on failure. =head2 warns_like warns_like( sub { warn 'First warning'; warn 'Second warning'; }, [ qr/First/, qr/Second/, ], 'A test that always passes' ); Similar to L<C<warnings_like> in Test::Warn|Test::Warn/warnings_like>: performs a L<Test::Builder> test that passes if a given subroutine emits a series of warnings that match the given sequence of patterns, or fails if the subroutine emits any other sequence of warnings (or no warnings at all). If a pattern is given instead of an array reference, the subroutine will be expected to emit a single warning matching the pattern. =head1 BUGS If you encounter a problem with this module that you believe is a bug, please L<create a new issue|https://github.com/radiator-software/p5-net-ssleay/issues/new> in the Net-SSLeay GitHub repository. Please make sure your bug report includes the following information: =over =item * the code you are trying to run (ideally a minimum working example that reproduces the problem), or the full output of the Net-SSLeay test suite if the problem relates to a test failure; =item * your operating system name and version; =item * the output of C<perl -V>; =item * the version of Net-SSLeay you are using; =item * the version of OpenSSL or LibreSSL you are using. =back =head1 AUTHORS Originally written by Chris Novakovic. Maintained by Chris Novakovic and Heikki Vatiainen. =head1 COPYRIGHT AND LICENSE Copyright 2020- Chris Novakovic <chris@chrisn.me.uk>. Copyright 2020- Heikki Vatiainen <hvn@radiatorsoftware.com>. This module is released under the terms of the Artistic License 2.0. For details, see the C<LICENSE> file distributed with Net-SSLeay's source code. =cut