summaryrefslogtreecommitdiff
path: root/scripts/extract-module-sig.pl
blob: 0f161ea4126157fd673d755570b107e67357135a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env perl
#
# extract-mod-sig <part> <module-file>
#
# Reads the module file and writes out some or all of the signature
# section to stdout.  Part is the bit to be written and is one of:
#
#  -0: The unsigned module, no signature data at all
#  -a: All of the signature data, including magic number
#  -d: Just the descriptor values as a sequence of numbers
#  -n: Just the signer's name
#  -k: Just the key ID
#  -s: Just the crypto signature or PKCS#7 message
#
use warnings;
use strict;

die "Format: $0 -[0adnks] module-file >out\n"
    if ($#ARGV != 1);

my $part = $ARGV[0];
my $modfile = $ARGV[1];

my $magic_number = "~Module signature appended~\n";

#
# Read the module contents
#
open FD, "<$modfile" || die $modfile;
binmode(FD);
my @st = stat(FD);
die "$modfile" unless (@st);
my $buf = "";
my $len = sysread(FD, $buf, $st[7]);
die "$modfile" unless (defined($len));
die "Short read on $modfile\n" unless ($len == $st[7]);
close(FD) || die $modfile;

print STDERR "Read ", $len, " bytes from module file\n";

die "The file is too short to have a sig magic number and descriptor\n"
    if ($len < 12 + length($magic_number));

#
# Check for the magic number and extract the information block
#
my $p = $len - length($magic_number);
my $raw_magic = substr($buf, $p);

die "Magic number not found at $len\n"
    if ($raw_magic ne $magic_number);
print STDERR "Found magic number at $len\n";

$p -= 12;
my $raw_info = substr($buf, $p, 12);

my @info = unpack("CCCCCxxxN", $raw_info);
my ($algo, $hash, $id_type, $name_len, $kid_len, $sig_len) = @info;

if ($id_type == 0) {
    print STDERR "Found PGP key identifier\n";
} elsif ($id_type == 1) {
    print STDERR "Found X.509 cert identifier\n";
} elsif ($id_type == 2) {
    print STDERR "Found PKCS#7/CMS encapsulation\n";
} else {
    print STDERR "Found unsupported identifier type $id_type\n";
}

#
# Extract the three pieces of info data
#
die "Insufficient name+kid+sig data in file\n"
    unless ($p >= $name_len + $kid_len + $sig_len);

$p -= $sig_len;
my $raw_sig = substr($buf, $p, $sig_len);
$p -= $kid_len;
my $raw_kid = substr($buf, $p, $kid_len);
$p -= $name_len;
my $raw_name = substr($buf, $p, $name_len);

my $module_len = $p;

if ($sig_len > 0) {
    print STDERR "Found $sig_len bytes of signature [";
    my $n = $sig_len > 16 ? 16 : $sig_len;
    foreach my $i (unpack("C" x $n, substr($raw_sig, 0, $n))) {
	printf STDERR "%02x", $i;
    }
    print STDERR "]\n";
}

if ($kid_len > 0) {
    print STDERR "Found $kid_len bytes of key identifier [";
    my $n = $kid_len > 16 ? 16 : $kid_len;
    foreach my $i (unpack("C" x $n, substr($raw_kid, 0, $n))) {
	printf STDERR "%02x", $i;
    }
    print STDERR "]\n";
}

if ($name_len > 0) {
    print STDERR "Found $name_len bytes of signer's name [$raw_name]\n";
}

#
# Produce the requested output
#
if ($part eq "-0") {
    # The unsigned module, no signature data at all
    binmode(STDOUT);
    print substr($buf, 0, $module_len);
} elsif ($part eq "-a") {
    # All of the signature data, including magic number
    binmode(STDOUT);
    print substr($buf, $module_len);
} elsif ($part eq "-d") {
    # Just the descriptor values as a sequence of numbers
    print join(" ", @info), "\n";
} elsif ($part eq "-n") {
    # Just the signer's name
    print STDERR "No signer's name for PKCS#7 message type sig\n"
	if ($id_type == 2);
    binmode(STDOUT);
    print $raw_name;
} elsif ($part eq "-k") {
    # Just the key identifier
    print STDERR "No key ID for PKCS#7 message type sig\n"
	if ($id_type == 2);
    binmode(STDOUT);
    print $raw_kid;
} elsif ($part eq "-s") {
    # Just the crypto signature or PKCS#7 message
    binmode(STDOUT);
    print $raw_sig;
}
7Ux9z:m"&j v篹Ȅ{ F$ّo/Ëlh6Ғj؃މvR>~6Rq:]tt\V->zLb[a\a쬠 N4$T@uhJnB-ə3[8 E^)r˶FtɆ3+PތqrܒUeRP`I.1V[wĬ8a&Xɐps@f0@toQDSCA~'B>&6JBI ց@mW|C OKʱ栈ؼ>(TYN/o(,I4oeٷGΎͽ*g0 ]Y^.}uQ})>_ޗfmw.zpY:_6"'}"=vHH4:Z?=Sh7?ޓukKo+[o]ϧRߞ6eWt5{7Yg4V9_%iō9kӣ8z/h N:q|?ZXyq^s_w]yDv2xa{*rg7shespcr/׻ѶMM9]$cCljv;\ד!/)xxˈcm+澤sk,D:bgeB/p"zr߃+:, X6PV[N>/f  a{rqyx ®岢wgi,ل+ܽ1?7мW iҫߗB.ٺț1/U ( T!{#`V.zžr fUx;Hr{0lrQF%c\yÇ#l3}m|_=2w𓁸ɥ?S]yqE[]N|`vO_.|֕*y]2K!e(=4ycsαW[[5)Ek5>j´]:RQ}ߣ.;n\b)u,aHH^>s2=.(zj.hX/W7 YH ?OCHo\MCvO=h J㟞YYM$Im)-HI$I?*3*0(*A$yH$z ߯-q.Y)@ {,ʸ 9';Y3=w",wds;użˌ˿KfՌD61l*𾅭Nƾ\v{㷔I$I$5uI~)t)_*I $B3N> oR莲0#/ Ltq_q7+37:w>pu|n6H0#?ȀMM*H#21p0ĈJ  AQ0Z{Q CQ;v0Nv|ۂH&wHK% )&{yp? 2϶AEGت_D*@LX>{cv6k=NCJo; pm S݅@VįꔸD LB>조q /.e)U$=K%p M I ̼ k󋊙PEX.3Mzj gyn/D7H$#`7ػ*6߳j)#d!2~_||sC 5=|a;r;9(z _ A_s2u j8`%j!Q #?X ?gr=N~sTцҳUtE\S4).q 99b>[ f-"-Q<_+cZ,m;]dAI"ڕdXJ6ٚ@!^8^Ӑ{89y!o{d L`bLAyk og+Q4n?JQEDROru_dYG? c]fIZނ:#zBס]^XZYCUJ" _(qhqS%L/s\sv) R;0VT:.f$0H1 A1%M@{|LϦ۳wuHILuhpm(h7~y'mw)|)~A^ۿN/ ]NiWB`Zu q/w&gc8} ]s6f +t6,ʨ_:|`*"^w[Db#|*&gl^" .&H|r d{EnF}`h;6C{W{E3)V pBH$n7.̩Wszww+k#!y,aErGO 5:Z ?_H!,us뻻}K(K.E{ŮB|W>~>ӯbFYANZ|X'S!`~/&r73xeS87c~?´wWNp[ʎcd"Fv/VG}cr>j]|؊x1¿g9^cb|xu1~"J6 82Ȟ%Pxʴc ٭IºgM0A 1DE<@  *sz>BOa]#)]>e]÷&펙[~X{sWnM+k6(6J|.!S9tTqVS |$ "|*::?  bGYDCXz=NCʫ?}d.%6{7|,/?^p@E۬6kj>c{S,-%B+C1~6O<@rTI(:%TP#)iѕzM%Gzyo="}7^z8k[oRvȂvq{zb&_쵨ؓfh9D`cUK5de^etkV*IA:S~j !SÛKD?Ud7NBZ_ߒ.u$,^\õ׻;cm#wrp唔ae)v zP [O>WΝ=̳.&bR >ÏW$%=̼}v)Qw_ug*[?[kaNmd`'v -Vb:~~w89nL=;#ok`Q"96Rg<:q-զ=wsZg<<|ODyS y+ORY2|m\!B;Ht,Mo[{}~Vrޱ1 !>X*q _4K$ŷ*Uc[1c ; vjh`V 62^L@xB`0\2aGX07Ky40h&FV2tP^calWGBzBY:]rQgz=_dR:S:cbbԳ/eKh:0puR(\S o-1v>Q<씣~p+( 9w,mzqtG]uZ62 ѿO>C?yD$DBj2Ak{faOv\)ц}koo.VXUEn9x| Kng veCR6cx 휮C떞Yz9[vz̫ѫ:PdxZHͳAϗ9U)k00oHw e5Qim wXC7/h.8㓵Xrչj PD ެI }dfHMy fCK)X+%k~ɱVߓ_U|%Jϩ~TL4Y9"qTDKyC韔Go ~h圿Y'&3O:s!"V|j7UęQau/P ˜lt&j Bд~8Ovj7͢wRǢKR:x=NHȉG9h(Jtp枪SۍtV㊠V3/LҲ7Bgrgqpξi^6a"Sv2$)ea((WY@ S"qBA#>]++lef oEBUqsV2C9ߎR͖lwӏ kPо,?Vv 5ޓvgUE?$b~}sXf^ gRg2ihk={9aW90@O'MEQjKC7ы,u Cq4<#yI Jx[irwsE'#әK7#cVжA{/em RFMiy\FU:9[k]|;Rk!75%/,7v_|}1Gf,A;)͗F[>y*o.M5[Ji|e: {ue?;q'zW.̌FD@ z,׋_qBmoeR$z?B$*c`&j_L[:*a2bUнΡ߯N':UVp$Z+6ŀe@i.y.ypSkcB.a>kNsG7 A=S 2ZK*yVhQu=커shSN7e~(#&~Nq˘?eW9vmP&At4q6,jXJMslQ' :r rȏ_?CIHOøKwJVWvc:QJWW<c%Ô* ce"5sr>^ yŘ썳TaͥMV*/;sїЏ\I)Ɩ* ma8B̵j޻z^m\WOw_5ޯ#Oz{<1ަW*Wcd$ Hvqef#[_C #8I I1DA [:Ds{CGTv~Z #jߺ?4;I|%Ω{a-̊i`kOy]1W <Sj hz _^ dn⠠ϱM?t1SvƬ+Ǚp@ v{_h{6SN}ٶGo_F>2f, b֞gnk'eg;?<>htQ;#?su[4g?xǺoЬk=7 ^<}H_¥:)FfBuu u|iHD?E,ZYH\ߗ-H<Xۧk|1N%nNJصDv?^Xcnԅ ۬'ލ>o=~/݊A[cbҶ-oU79֞0#IW/ *fr䴑TɴIo$ӆԏF7n8\)&)8@(>|6va4_Hۜj3B[{هà Eq;'jP s ܲV X 3 :[^9e/𰅎qtABᴠ KuvR<ڗ~>7эvDӖ r0c%tA-A*c5N-ţe2HB _V]ٴ G,"u;fkĉg|\UTSzn^]D U z6} O LzBI$/PN/y}'r𒀷шJCk{T;_f0 W/æ9|x2 c7s0)6k[ݵY$!ÜXWZAFUu98CN)-Gǣ59 (!0]NH9b?E-1 n m~<ȓeԪpF:hlƚtMDoз⟯dl&%:Y0 oN ?EXZMzQ"_?$ 쬾-|`M~aϢ# pNo>958u(%9x/=y咪T"Q{S!;Y-`a+f!09}}H+tk}vKP@[DM '۝ p@NGONu,badh~߇.dmXAD2Yf}K'L(3L **_Ï3>,,k\5ץ>x x( ٻYl\nD@}%Ȍn=uqk#dE oK]#%Z`*[Ի ,OŐ[ef37#jM$i\O]I"F:߄y5KVo>^lT96-.tEEC3ć㪀 /@6?9]_ o!8_xA tWM9/2~r8`;7ιUZߩ3e^-aޏ6p:@'fz}uDb:oa(G`óOwU(`6c` Ԝx$OGUx^ k #;~v n0']dLC C{xaOOoiuw}+2b!UV϶{[7 ,N?6һL>ӹ| #MvP㿚}@sIl]x _kɜkCy)r[&1aA~}Z^>gfo#8|ӀuƮu$%Dg𚩡F?:յshN^rt?ulU aJ#ђоȺi᳥^S妴@#F ٨;cj ,@1dGt޶$=DԭF5jtLn̏DA֙=O}09N `G=i}CJ`|p.j<SOvAX)]JMdx ؔ5KJVit Ke:I}}&EUm>ifyIx葲B];53-;r)םX;ʻ^z%}7 -}͡e#)`9ܕ(!I%'$Bvun {(cKMJͶ\ _9Z/I g+#j}'=OF=Û!Rz e|p; Fk!j޸S܎[ =ddU*>ctjAU&7>r^7&XwU&,vzS+65 y0w2Y a/8+&T#M -L Ǡޜ) NF:PJ~Gqmi [G"YseqMK㞾˩z(j1D=C`6g'š>o\wlܵaq-z. u rѼ/(?fZReLM^>1g"i|O(3ǜe_EEú/ЉM U\e Ѩ6RAH={*Iw0oMrԔ9(j d(d19?m%8cD,i9-ZJ$1iuE|4&&ibpUڐ4J6qh(ˆVLL5HAϺyJ;QNʌXbmXhhqp˔p~]FbȩFPZ UmĐXl; b]t;-2xK|J k͛ aV"M$ /P&x'qvB s߆193nd-ʇˇsAv->W YI#Q]@!nSZ{W^HÝEm@ ~=60Vp-S4Z IVmH|oSЪ%PRAE(8dz^:.--Z\ìasS˲ӁuUav&|ի/V;0#` [A$[%n|y>G6kr]$>'v-MsCOm=p'7g;|{!O)jICj/Մ2BxeͅO]!x=ۊ']JӁ\PņڹZ6ω)%F "gSH7iQ]3\ 'Sx=D՚ S×Q7ҷ\gnH)` 6)etoLxſ6j\ B-M'QNf`>'A$L'?y-Ȝ*rԱs"7naj=rM1;0L3Gox7\>gz-O5jlfQkﺥu;{޵Z}kSFe۶e@GYq`}^sVP{m-n/ɶxuLjߚ [FN< gƱx]8]3QU}L (QHIYIJZ-MyT ]?2-sC9^I +fhʍh;\D;x7[{D;ipm.̫C^k5vr~2=IgK"s6o k ij^R*9%;lsd6VΎqf/mmKnY@Xwr3⤅W`-j\h}Y1νwfT!6LgxB19{ф7nq2Mir(1WlW;gh4jPW;f?6  9̷覻;/ _ kw!+!ɨ{ _.~Ώ8Xy:Y:M];_rOl"i䚐;ImܗA0ְ;b $ ɗ\nn_|;&O &WS$ގ2 Nr9J5M,:gQ!ߊij8X|VFwR#+D_6CkBQ*,DqOG*SY*gݓyS0T )&.bSE7ܖ % eQѥʏ9v@A84 \8ܮ-Czw }Yy^3SC{tY öN5TA l_Zl]7G=A_OL^JK0889*:eDz&1g Uw/27ͻs0^R`]Y)\\]+n/lO/sE&\;Gdz ^{>Q/[FuZ3ȟ;l.uݦ[#2Ϛ?xSuf|zlt_f%Lt]IK+] s= +7z>yRZDK6cjCpVLgF(49c96σA/~ wn{]|2dFA2ѵX6eV[c\4%#46>~?*\ÿ?E+$A1K QfsUFg쏜+d 31t ^28qQLSΝ?5M)`$(9RA.\pFC߉ѯ(:wHxgW9u}D *fU9?h_[8)|B՜ I ^=P\s.Jc]=>(n~o*)G'y\XyW7qNeYA_tdL[.gMVCSfsmTX#.<Ƀ@ G>aHs(0WH*uk$SmVmI!g3:Lh`#A]T XX: V/9( \`rD"!G{aJC0,f4ew}{p.+OdasXKL& wҗ*{To1-`Cz3PVN.!f4摁(UQ5ZDZ#21jUGj0c4hDdeuSO#If9rըǣXMa43ٛ]̎4cCa{.WNְ1Wr躰l 0n8b !|j̶Dr<04=7';td $C9*q'sO򸞠x3SzAyG(z(P+Եg̡2#Hcz 7G۲G ?d FLT8E}\o8o]}c29)kNNNx6eazJ̘8R+Ɋ6%-2iU`ȍQ˅ht U5rYk[k, #!W|ub4[ަz P E*I@ߟK;C׺fgK&#JA 4cuFC\ f?+a(;\4|HOsanĚM}@E;`~$Ub9 R8JDʛMhT~7|/T|'u,:YHޖ4m7ukĜõ8f1X.i@\\Ұhz dWL04:%$efLv0m "qiU] .Fm6ϙY bŨ=Sf݃Q PHU&I:copkx;[GH\<qK@@6<%Tԅ0. HEHY(A~m|2a=5/8>n0xy ǧ/R[~NN 6ҩz۸b-E\*'fEAzw]$JP4my&`؆4|~W?%"CIbNN;1Z@| 6QJK_5V@>/ 3 s;[ %`#ם#sɰ`|7,D9 @\?HLGmT}_de8z 4 *p>3VLQr-=stF(BHya?v^꟬Gnn@.{WM# Vȍzstir{c̹.{Wg3bg6R}|H?-?nhR#h`ZGFF|`+ɮp}dz7N5Xzs:T*7Hp^!zNx@vr `/]\WÛݣjϝ{as&ެv&>{"AUA¸07]1ous٣!:D3q5(xrFAKg?Ю`a+wxC=]b2M7~lv=-#mZA$1F <0Pm`V{_#e}ѯ. _zklEc|L!]ǷvX7\4)z ]-n~Q=bpl[˄Tm_3 yd,[ A씡V`D7|BgV?]͑YY㲊ѣ>/_ }ERk BoG}vf9͏C . ^XˣU"$ !P7 Ζ+[>SF60C*X=-,"Ngs)r>hTZ5<-MeROЈ#9܁@PӼ7Xj2v|tڟvk~"m$%LBaљb὆V՗ )(phkq}pj & }AѮzq3uŕl< 57]Zmfu=+Bb&Ds(b#c5GqY#*22 l`enkt6ncMd1s Y=FE ]!֨Y[$dՌ/! ~M\1,qb/ Ãݾ{ރVs6RѲuG%z9ܕBPjh1E"g8Q0l0rE];ђ5ĉ[B ک1{M(wGJ j_V`ec/rP/KzR (PPinKaGIfsm:ҶL L0;_&aժ x yKi'ut׳ ܭ\}:mSgͩM'NN\wP79N'П.Pq X)ߎkܱ'qgETlh.xhW_ՆS(K`5j.*FI#=`^0Ԯco;GyL`ئoRƗ պ 7[Omjs ̸d[_T9m&__9ew3 Zmxoz=1,dR؏AB$\!>*䐭!F{ZX\*G ` 2$,_Ls_~9m[( 5XYžکJPF6,DYzY0Ejr =Bn[F7njXIohb\&?A׿1!F{5{fW_lhwh>uK8',ilEaL~P1qײ۫"\ WAF gξ% u.-̱}l(~)gh(0$OTk/>;^E`G%>Gy{Ն<6MSsW;JjL4RaQ!i7)˫3>[XaPOoU} .>*vkm)2f4{4Bu6C^15Yq1LBz$Gk*"QSE7_hX6j/JxbzuAPRlWF$bkb +ɧ0[&|ª{ 'xDk-a~GCԲ?c8Ӑ&6/>gk( 0ɂq[󃃟Ea嶉a϶֙LZ\%id;#;̨):F=n-}ogqfx@oˏwEې;rِVSo]׾c|H:8v#)`tt :GJ:竞1nz9j}0ۍu7_Kuy픥I}%23Ɍ;>ʩ7HfVش/K ьb9r%`=Kj2 `] l*$ߍ*D -#B-~'}+U4|F4!!Uj7(BDH5UKѯeo$^hvqyX7$q$i2>y/B7#ɑ}RwMng9xg3t gvS8sv{, *3Xcc9zaV#T_*x: ҙ* qwIu'_ (!P0@ggu{"$liѢb;~W7W3'MV}њifާ-6(yoe7t))]?:ۃ\0PǦ˧E DìAnAm[^Dq(y `8i$։~_IJRdoOcA. vI>-U9z)Jv֡"<_.n3 AW?tS~::q*an,COcmDЏ0(5D !8O?n;g3UO? JmuH΢ 4kCKdzDޮ~ vOi|j_V/X'eMtp,i6*1ZY>Z["d|a1Y"a{ڱm bʝa[l]&SBH/ e fGɸv_$UǦa&qQrnkE(EU!ڝЛ.db4%A/(3r@ .!트 tF](bδv_ -Qc:b!Vdߤ\keN:y+gzs;'ol3 sn$v\n_ok+o ][|GQANDbBbGVZYR ]5s,"ɶ}!$ْ5X"a .vC.Srr6psg:w: aϿwfvQT%/-K@bO֚~tqV84&nCs3ě9 kg28~[<@i3LKDnss/XRL^e e3P:yyQЙʺ[*gªGK!:6e"]LЊcm|?'^|iX"wCS:Hb>QFA<%{teYo@`3ă0֢"͞Mt 9qZ^ &`FUg~v+XRQMypm[jbO(_;sK'l/rz5 "9ŝSc1iFu&x9knT{N5-ɶ Rѯk9bW-FaM 07\K:}9?ڀ@W$nOݗ<ßn33Am;hYRXQF9^oZ\CAzwwIϵq:;t-ɡdnw+:vNH\=nwAmP8.e>v7^QJzQ?ĤLRlFsg{ͰGW$[_1"M phR#џ=VY-hޒ: 96?_8)݁Y i9OJϜu8i)o'^یWtP 7•_,D*G#*TMexxG0Pu~+*LtZKRyUIȅ®Lgo+z:J8Sr#J!+@F,*+c}y_`uz xxhpʥUQh v?ѵ!0qPWg!UBG "5}TnuRZ{H!ßT&倫MvZ;4~ E85uޑ&<ܯFKwå'09U؉d'`݃{sG-c( vүKQ@s~?~sbTTr!X6>Rs#Y MMaCFa`Q1.CWpRW򷷢b UXaY[ѕ]sXg]ʵPj h*Mw3!eũi~͝NM ze H@v3~JcMuzX.E!Ʊgl>IK,j#Q=|ϬHw",QBjuܴ{O2s.V0[,ܢ"a6j8;b(lT BI6I!6]s޴kG_*Z3ut{ *PHzoAa0J;cHG,6ywX׺k\!LOTaX`&= Z/C$‘`+يIlcn 4 `0-5@gqɢA\ $?,ˤ]^(wVHpv=[͐;JnxoɦGPvE?kA'd& 2;ȵp,OdǾT˦Gܯ?j8XVqE.@DlKr)(wZ{=Rd9afobA,"GsMPAGa1- y×^buRz5uŸA/W\ xBgwi*ʜ]|Ny~&YsM4h ~وx.nieݎDZdB'o{nϓۛ9 e$#nE@QhAD>56)wz|V/dZ7CJH^< 16ߩn8Vm~:äV`bP;]=,wMLV^"a8ys[%.ׁQsX1p[,}Т-$l֟"`c /ou|fبhwy`q8!|l$zĕGza܊“a: H'5rln[>GKB݋ƪ+Y^sIS_uf5,w@C͊c_(Uzz:~fM KOY v9C~g̟/j]6rJ4voppz7T~~6xh;w!FǶ(,]gpX{}_[k0AӜ@#dwj}Y*[&:fn030Q/la:k&%0K`HoQڼU21+UZBE$G=T%8kArʕ_Lpc)Ҋ"gKs?yBf$`aWW3MyRѷVT8҇`}3hbmTѦՠ|pDGkԽJ\cu?ps5I@Ʋ{vGA+Wx,!᫶CJ/w"}㦨"TǴi5C]N1x;ԐeoC4NZ}3e󡿹hBk.cs{P !ˉoeH%LV5o-ҿ0[)fKX0.Im&v3Eܸt}Z*YЏ RH!_gf틷mZԫvU8x 'ES$XM̉wzI+j@B I*Bscch䆌Jq~il1p; f k.3bqwΈFdqrEZg-[vzkuDmbRfFskK|AņR*5~ 0E CIe39Źi&[X7M0AO_ZmdGxߤ骿Ke/i0EnAx˧ucT⹣(U㫦Ѩrˡpֽ2anp*؝ ҭvYJt9c=1R$1+#.cD}&ִom#Jy[ЫI.d8вp6xڟ5^"F_7q̠M^SZ0Ɍ,cKB-8kzHC>y֊.xacVq1Vp!"L MgZ" [v Zf!DFqV'5v}eYڱ.A eQ,q:lzS/U/Pj9der1e5)U@ ;uf;& ҁ*1/Lfcʺc_ Kw[MYtr8ovyT0Gw/kOpLv޵TR<{?s8r9m_+RɹX#(EAMA}we +{rh$0 r(Fɖwvx""Ɣf 1 ./*zџuOl簘}.OnA?Xԣ7z ˻0ؠQȡ5)9qIBl,&nK?^FPa J8h (oVfk\2y:o{}+U3\DYR;S~Bڜ1}gz"#dj^]!Ĵ!iMo@>)˵@5Os:״=K\s u(Qi~\/aϞ@s<{aoZJJq/w̹3@6JeR WOkm$#a/-Mֹ _d6RO[P q/0q-gBzb#0p H/iSӉSڶ~n1 n~חqL.3guI# %8g՝h$ ygu9NَT;;,Qҹ91?7˿|zL2{nPe z.}NC֐6)uЄ2Mg_>ï1 З;;oTe/jlcG&3~ֽZY-~/4Fb >[깐/70^~cčsE΢901"@DڎURT8Rj_tȆkMyݓȇy_j9i#C8JDQD]fu)p*AǍJ tg 0sAc;u8@zLi@ !gQE&J:c(n"{l]p}2}hܠlBo!'N|ۜ X?GGI_z&+*Ѹ[@\@ {cZIƑa|j-df3ef ȑUɧi66|[ xWJ6=n5&/H&m]4{Q{!Ga2#6C9Z%OoЖe`|e$" UU 3^b'ӲknnBMٮeů:msc0salXX0-j &6?؃K>5ZI=jOcKZgYKJAQ]rk ]~DY\x \i ZLbzeC9pD<) ?. {|0Є-핳-0*}2>wm(b9 BՌ<ڒ6$`r_q3L! Wjll<}1ps=obySl^ŠYAQ ci`jWk>?EmX=iw3{JQ$ c;bY2^E^B|\MiRյ96Aw}]>p3x/!8lr6WiQCP1cZ5oh>] I nJ 3oO&l5/ uiN۠]gRV#meB y83ufk{¬3T+vl/"YYۓEU*(Z.4UPt6zÂ"kE1ͥ1[îV7EÓ'D |utГpTlb״ˬD2#Ojrs: #Et)ɖl@[ܣңkc8f;5ETܷ:fjwY?L현:l9U( lrmp r(*g덶gIٖBͲp:QJLiBD^Q#}EW>$ X7(0Ry>׫ )W5 0J 3O7UC/DdX;ʧUXv-eᙟ>tZ{Ѫ"Go!_MDTV`s0qm "LoeW4V\*cYd B/{!,_ܾխ8Rl @Q#U4a^~PIsXjT_˕WGDO5Cs |{\bD"UߘMG[g84(;~sGˈHF HAtgh̽,Ǡ- #B]yR^|_&'!B"Z8Y{씢Cn0PF^ ܳ}a~)'yDkC.qb0jB*l7a5ִɃs0jnI٫P;DF X-ruWo,k~Hqa]5CEUzXV@nCia/] SdTrxMŬ)4ȏ?̱vl Ak kGw?Rz#KET1 wt(29$ 9SNAEg.늧sĝu8E뺚@ZN&B9QȂOGrfh헌}DT3`jH~qb3%zA_ʧvûJV}+sp>~`RdoPIp'tl"1aY-^4Rk=YE5L\iӔbW鹚Zm^pL9S@ qX·v'gnhۧS)&C]/|G<֎j{?\cktn:l\gsZśnqX +tpԦv4; Dq;y; Z)U4 >V8q2xFF`)Ȇ'۞q9tCJ1$1,d̖jžR:U1C9t۬T|ŇpM;Ρ]tRH*OBY#8/gD'ٙmw:6b*vw=wE %nT_ʳ<;=2ƅ@'T`$vꖷ=S2CI%*י9— >J_Db2$z^W"r;}hQPۗQu;N.y(ż,e%-B`C01YA8;xS)=4*xJr"}ovN."ZkW;7#,GۨŽgZpw@='|.GtQyi_ʸFX Wh{032ŗ|י8sG⧗Ȏ"a,E#cteӇ䅄z_jVo*Y&81'R:m *hg7\spr{]pRf~i]k[B+Dr;O}z֍Fx Cu“u۳F@NE:q8eTcUA8P2lӃ1BDFxr9oǮsg^q.:a]TWYpli/=uirw۲@onf<7X94煯6Cy=\Œ;gmJ+! ?^p> ٨i҃ {rtWO YRLj^I_[M֊m>֜y"X;*2e:n|,g$ 5 9x:NMhqy:LGZZtiX4qj!q8/ d9P,#-fE)T)-q;Z53.g[_ڎCz2Z4]3#8<<՞s#dXė|f3{՘vg.hF0G.ElvjNkYPd!Ҝx0ڵxg;J.'H.b"6ζJ%VE .sm[h ɈnԨ87/Tdn&7:$]+d[\.5džX`5隣y!\l]AR˶"ڍ$ZO'u8&[8͉7" + &=p 6W e[]y2."Q4/mn[ڻ(pӾ1ՅyMGx2bqSa0bM&{A;w&b:Wn!˝9/> fA5As%SBxm3,0ŶXibJZQroYf)jUɝwSF;3l>j"%3Çy3L|if' ^壿nMvL,Lo3YG? 4as3?'\z^j0 u8Z!ĚkWYx6ϧ L3Ξxɸ˚*^(58YM W;prd1 G t>!!WP{AH2f0ʠ`UH̿\VdvwԣSY\Xվ62ʍ'7|MOݓsqNQVdgK*[:894b LS~54>{EW$zmPH,Nh{+CX8Çs\"}G.x`1nמz4?aYY\&o?RHe|#&[< /WS% t&oHq|V@;+_u:a5kơn (c[I*0kT9ͼ^, 2}wgdc6ӗ5L#QMIQ** kG5nfJ _|=IXZι-2e%I䔙rS8E162C$Fsмq9OyfĄΰ"pŖ8*ȈǞ6vRg Ȧ?H'?4b6~!˹N'e.̚Cq8%״1D7(g Q>%3߯ 缎:=['?R9Êd>}.z3]q>me3>Z@fU%aO>TlG1e}RÓ ?SO<|9(o1HUɀW U~0(ŏ" hqdxqXA' 3c#CZYNƵ/Q,'1g㻷Mg?3QWgh ȯͷŒrV7fיjdGej]sPY%zJm7 {fՁ@2̃  [N#-|四uRw)kdٽ7j#g+!BHq^>*Շ{2$`rN-}G'iƨRQ?Ot^Htׂ:]Ɔ\k'wz-A #gUh ă)>|_v _)2Tco7D)G ΑDn:vŨ4B dA.V+BWær c LGuv0TK-0D +pvYu\v&NݚeX{߉{^o`2[T bCIf+{b^X֯{{ϝ|.6 `<4¯Dڪt(wq\kwǾ<'.063-;TMӤ o VUOl oCo?đabdv|PDD4ǥC(y'0d׎ag\"W2Ͷzj|kA+YK9B$y4Z|C: ,丟ʽ6z#W~ɼOKzAIBF :/!x1u} :Qgg'4F$,&9H} :j!EAďVhGkKVө [5?hVSWͽ_8#9SA <&*#aSXuίl B%ND0xYwLa_aT#!%7Mujn0r$8)Efpaj$Ak=^EJ]DV^0:JrHJrY繖2!K駋o-C"؁] *r`M5ǘl`4UuwfjdkiZQ+as*Tdp^Ub&IQp;f.`I'n쬾hQmxg+Hm$7Qҿި5kܼfM Ӎ#'ygޣGnJVtUOz%6sQy|o]?1?n>zp~O[Q:FJ)|7`,I=S{Vb,E1ᒠtg݀yEV-Xߋ*e%O0y5.#+)E3$k0ܷVP:"#ҝ;ilU3ښW5*q 1PXа_ Dθ}Pv&ulJt%gKD0j7%cH㶾mC&3h1dIK|m`ņK!QtW$. 掔ۃë/Hcsy! ?TqO;:Ѧ{ߒTR5W!mK 0E.2`d @CI i by_0n"͸<+}pAv.Ljl$0g#3.4ؙW`,hv_ʖR=3 '>Яgn֠]!T[ӱTCpJ՟opY:먪%MP0y yv~UHIgE?8"M9yIFְ2}_LhY+}ޑvO{T&;aF}esX}BZI~}zTRa+f(QƥXs뇗w?F(`Cz}J̦Y9IZlC DJ?V{hϹC[,U"x (,JWhsv72an#)=Rs.{BX4C1{j‡:z$oq3e4ek - LS',k+bnx/ESڠ} ]FH ] ^ Œ#J}URJ=Oq^z"d#v7oRc닰WZE|RMpM(\F,|ef׆(C<^j &ӴALFOkq|(2;8n:ϨxXSf+^1_'5xb_:m`ZMoD7natH't7X+%Y֍jEgi19&x_MjHz8>F$i٨} U,tV,^^FO[N9 5N/x=mܕcZd1(pL{^o)rW$fZ\d,zyP]A3鈱(b_CCwOV)̚o'}IM׫R~Aa/?gsA  <뮡ھ=k;lVcMA,Pj9{{}16e{miW{~2f\ρ;(0tB<InToP({ߐ"!7?7&nҟnD}ŇKy|/PoViZ^?g}nìfI׍ڨ&fV/%fٲ嵂^O% N̛0̬`UupI <)ke/*1$c37qTxU-oPKu51F5FxTT *ƹ+'OŹ[\njKkWYP.w_Tf.DF߮t%%&j"xL{W[wNURZWvB1n(B3 |"$?8m/* -&礳quX#eGRwa'oT\eqL )xR270o<_i5ޘ`ꞸkǪPxp'T#k2R7|߁LgnW'gV@r})YxӞxu,.Ms"~OpQ-զfnPCb3e/;gmm栆݋%2ޏƞ?BJ&?* APSX˶PRr>Jw&H:̠8eaX~x=u?4F[7p1̗eO['dr&.3%QISM4I .F]_!= Wj<~pG=z_9)kVCKD HlL)D1կ4G՞5R J Xt;NdIxKSI?1(|}=0+F$J$ `u"&{ CDnDHW$O;=CIąR?l0:N91~ u4!eL~ !)hw{?KMdrYE7>v˲rB_N*{XF&F#P>//#]b`R뀢du~j <]z?٦1꿳߆vj.Nos+ww{F\;PWa/6Ovp_'F[_`Ä{ޱY ` ]J<<^iacc?2P kQ @"4whA~opD&go?e?8,Mwj]@m& CȢP, tlG}qHs 4ːTo1:\hH8~_/h!a=uO$ ,vmu>;nKa>qۘ~1έ)l: E[WSfzN|˵cB_1AN }^6؋_o,7nQoM骞x~ݐRgAÞH@_W<~?6A GGBJ } j?8tLM~^&Jwgd>,yàQ9e,/W穯Gmtmÿn6+9v~TH۟.ϻ _WRK1VL ?pfU0MhMxzG& իecy/v;g{4UjsWf"Jg?l|s]´eIF˜Gb`ovhP^U#`q@2DY\jt?b^x?̴)Wx-i|#/'߅/22?ɸ:n`4fﵗ'XEa{,}3 ه=J=|:==R9f^;臋]?<}Ǝ?&fmhzP[=u8(erY|pKhtN#~w~N(\@|=>}|v/Z~\VCiSsb{7+.tϳ ӆfs9);LBul^Ed'9 YwW1AhYu{)WtZ fl q͆Ewʹ&חC^ߩ y'3>=?6IcN8*p(5}){s%|U`j6]S*wcf{u{,*䄷݊aB"KZG*Yr?2DA,H;EEAu"TRi/_X]1{U3 /IGF:ffᚽl^Enp7Kw(RH;w!U1<<5CAE@τ{V&s|jspt'PܜAm?<ۂ߽-|E<0<"Jxi93z+*;p 3}S2\M|!z:;IWJXُOI M$aw:DlQP V _# hG)te&= :x|ve|vz`LQ Z^CܲpFį՝ܼh?'ok%ކcnfsl:E]lxLMLJk(L*IQx_ D8 t8DF5Ҕ9de)@{E/c5@0@ӹw'[O kZ"ז b=%EuOӻTL`9:h_>"hzeُ@UJ(QɃ~y!ۤ_G 1\[u,v=κus_Wg('w&7af={>xzmiٯ[UG9ҔJWM|Wu2KhQ,$G~7e/`M# *8$7.fT՘Pm=-V<*ۆs5:u r$6l B3Pi p:05VLZI/~Uq?tZ G˘J˩kHaog>/_MYh:lt#Y_y=xzşt_E”H9opvvs켖8giZuBto,V*c\j&M7I銑ؘ<in5*>UX|>5U:7߰c5n#::ܹ)Q sWf_ ѥ9Fpݾ%/ͺb]jge?^j56UmZ:[Vr$:~po l;ҽlgRũ$U%:m+VHX7bBSǿ`NipPW $gv0XEnH aa-8)!+z"y FĖ ϵg(4)5^o|y~ׅ6x36ŋv#/n|Kߑ2t؃z5N^!H,Q6J9Hk~Ѐ~!?yLy*X8קiCiR5/@H1*`UPr 36$.;nY+JE ؞P;.~$%I G>v> ,?v,擄@H !ؤ0B$w2 K^ d)L`!q+㿶85U7-~¾0O`dJ)5"=e+oK4%$ѾrS}.5xah,3h>٫daAuޮ@z":W̸eym%+;HwpyQq<`dx@ dd6i2$ gV:WEڤ٥VJJjR/TAhzײϺ-X7q>vJZiMVޯuоAW"G -I1Yrdb+[𫋿_l_zy<9m[]v]֭|j al +dȅR k/&*cn`(<΂i8UAH͘ zGkSjn>g9zeɒs d!Ӳ 꼓6nmeliN[X^v* -s{#d~躏HqA潛̪Y;.jQ4*(/fc}-uO74F"nưr`CHk?;4#Vqҭ`[H ^B_ևMS] !h{w9'qwȿ)1jƷK\dGTuU{VB6[\şdGvUSVvI='RQE =M"5jS|(خ1GA'%3tتH>p||9_G}7Ap66Ų4P&D@!HȹW1e]wӗә:tX,n`a2Ϧ(ŻD:Ųeqna-6uvpHnQUPQ*Rɀ6t11{=(@Ad=X b{,-/(sm+_j\bk Ji}\(JR5 (jQF~XC`/QmIlwd B+߄kiE(ڨbS#4&PM2+!M8ƦGs7II"3拦GyMcB<; I fLp/j3\lA ~W*'!*!UlةW^[ ZbqSW47iY vZFǩD(}YI?e8FLk)#&[6,/j ͘<[d4!+cSѓzgգi6ll,^O<(IOSWv¯bMҀd15`^ݳv/X:ҋe0*e2iLXVt30PN=3X눵w+"oBEGtrqq@_cř.kkAP!8U B%;djiYd1wd,̓Ŭ"DJpJ(.&,ߡeK g0YH{b4?\b7@͒MɚQ_XOtXQ>Е2"FO''H{+a<{8%Y _]>#5"5WFffD| }aEg{zfɔZqf;ֿjU#(=죉x6_}dB?G=W_cի"AwD+N2t SI5]MN S-,St uÝ\vnħWTl{K٭]^*2ɨU ˠ;|%GKácniMГ]##L*V݇o"*7H6Pml$M5A<Y:rsT2WFnSz~mR|"^s"([%Jb;z@ {aY1 ܹWQ#^9'~և|.V$0PNSRWib I8_Al2dz46X r4 N;kZ>n4(1 h9\$8Mg>xE %"3\bS$ S30:ڏ<:uTB{yPmjm`@w #lp~+~wO-{58~yh?>v\nl{9zXo1_ω*sW?%0!lDz7k}Hޅt\S8i+yV İG?} )-2.Y -^. $h!er(FcN/Xnwv}1yԳ{ ]v@yf~h>:rQ{JnTP 4|*1ЌWvAs@Qe raw u-~5?"slSsuKi=NgRii9x`slŠ Ħ.#jex:u4gF<Qw(xpvFFFԹcNO2b=1#-{ 5/G5龚lw \'AN)A = 5|׼_S;YˌjyWG亼 WUOȞf#q5MI:FHBjU[V5!mQCd0O#- ˍݤ(/bD5:#g^~v, kb{ϤFx#p4::rYW\JCKR/pA߭ u TRHq^A*fBkt滱eVAusky@ $jyvy8@bAgPBvaaA'JBe7itìϞ)vDsCF>M}}w遅4/(e 豨oM5Fm˦Vɀu m(`Ft[u)jf v=*y0l5ʘ#[ In֌ЄHРa[iI.GNV7f!g̑e< t7G߆]af8 eH`w %$fCUM:"!&v\0bj9zEq!-O<TU>{z}]KuIVߥ\Kَ# $骝DtooW~b1W aⱲ8ip52#e[{a֬V{K+#9#F=]>EMQ}|E_lLmpUhOzh 5,+7cC1#"*g֖XFw$ d /έyU3_Ӯ?ĸ 5ۀKsXwurs~hESGmZp\I!xGUd]yuVxP9 **;a>MGQt娮-_wذF__nFP'&+ $@z$+x/!A 3;]f\U8}UUx.n1:EPPƼnz(*'8WgD.*Hi{M0#TF;>kw[>Jr(& Y"#a&m|QX؋dgΫ ,eWEdOX$īp˂F[` :rIT4fΆl9dݳC;c oX ٓ{E]G<;V$*bHj6$;@cPIXT#1FF" )({ !W;{ǿW*ua-Uih@ :Tʂp{q;DKaWr'K/"kxCWGq=["^@TsJW|b$2b*pg6BzQK PϿ&_mEp@ULP] r)*{m.YNbS嫂SòvZ@!dS bGUZ*& 48cixD!$(9lrp6 DEaXA^\8oIj!@%;o. ly=Fw#׎9hWOD;!DtP7GhoQ*rqA!50{6[nVbvEXo/Ha^6V3 z\H5M[_8PxKў i̺@ep%R7n)zmj@IW!IH0MmnFV4٥heׅ2=C=y2M`eBtlg0TscBNI =kr7[Fzt%"t!DvΑZ S+p*CB;p͠bߪ_^$X15#KR[p>B*.BG`B!CI+|8s0}]N;RyaQȢ]GBZĀg~%,-KIJi 蕫A2L/f{aeG#WBa2}f N2FWW̽q\ ̯J= %˪-T2a)hK>T"e󴿲F>-4[HMcKH!! 0 \D<w_UB,Tx&8VN;ݹu\I5}wTLԧDD)Q]MO((iDXh~L1{hE [S̵f٠h CH hr"!1\ IF4inr#VIOccׇ?װ^ WyA]w?y4[=){^?v23=|Z#]3 6 *6My\+d u3etz?:faG;z+ˈ]HHځ PPf.ƶ1p_x 3ߊ1DVc-UGАe$y3H] ]1~Wo& <4lb/Xu돇³*~O !(̓:]aؑ*CԀA<870('(!=-6P@K|BPIjM$N:+o6c,2Es$b؀i?_pe? H;Ixq B9BRgM3QQ%<V[߮X.xHAe.:s8A?z ?Ԧ1/ؘ?P3[i_ €w0 J- 8:.=Q%a8D3UVlQ5{&@ʀXڢ"'XHmw|/=/@Rd &4 QɘW(Pt(S]}}d˃DR$\2 |FGSs?ֵ>JSu#f3|]e B,`k:49_"McD=# in-8q2Ip ]YG>DU^gg1+DCEw$/Ka <UCK\Cn>їd.ζ&c KsIQ` -f  &*L檒Tc?#Ӻ6) ȃđI1c vލuV麬U0hH_a9DqִBC$|d(]LIdb>v\ٴ.ϳ@89h֔a~YJL_QCe]\JB]wehAn0*2*]{7m]BXbnep~lL}^ȯj! 1PCǙ_ui75%S WGx*ÿ`_4|np|\f0}~_,s wQni CKM_TYeẺ1=]k!~a!@^x@A#e.":U.L(~m8ܯePS`u~~"hS]QanK2PH1 `"<籒@ j# #탲ٵ9O?cـKw3 W" Bqt|x!!W+~W31T_]vXXj}),HmM@%1k_Htm2P+B*bn.QY Dtﴶ"YEMBi_nך@($#.|fqsCIED%>,R; h=V2a6ZM+ص{ײ6eU%)//"tcsY3,$ }KgEUeeXݷ}~6k^0fS9o*ӱ8^"~{^g.:tznfl.A!'DRb0(z>YHyd)iYs1{::LI`|!/)