summaryrefslogtreecommitdiff
path: root/scripts/extract-cert.c
blob: 79ecbbfe37cd75b4cb2adb6eee55f20c089fb692 (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/* Extract X.509 certificate in DER form from PKCS#11 or PEM.
 *
 * Copyright © 2014-2015 Red Hat, Inc. All Rights Reserved.
 * Copyright © 2015      Intel Corporation.
 *
 * Authors: David Howells <dhowells@redhat.com>
 *          David Woodhouse <dwmw2@infradead.org>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * of the licence, or (at your option) any later version.
 */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <err.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/engine.h>

/*
 * OpenSSL 3.0 deprecates the OpenSSL's ENGINE API.
 *
 * Remove this if/when that API is no longer used
 */
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

#define PKEY_ID_PKCS7 2

static __attribute__((noreturn))
void format(void)
{
	fprintf(stderr,
		"Usage: scripts/extract-cert <source> <dest>\n");
	exit(2);
}

static void display_openssl_errors(int l)
{
	const char *file;
	char buf[120];
	int e, line;

	if (ERR_peek_error() == 0)
		return;
	fprintf(stderr, "At main.c:%d:\n", l);

	while ((e = ERR_get_error_line(&file, &line))) {
		ERR_error_string(e, buf);
		fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line);
	}
}

static void drain_openssl_errors(void)
{
	const char *file;
	int line;

	if (ERR_peek_error() == 0)
		return;
	while (ERR_get_error_line(&file, &line)) {}
}

#define ERR(cond, fmt, ...)				\
	do {						\
		bool __cond = (cond);			\
		display_openssl_errors(__LINE__);	\
		if (__cond) {				\
			err(1, fmt, ## __VA_ARGS__);	\
		}					\
	} while(0)

static const char *key_pass;
static BIO *wb;
static char *cert_dst;
static int kbuild_verbose;

static void write_cert(X509 *x509)
{
	char buf[200];

	if (!wb) {
		wb = BIO_new_file(cert_dst, "wb");
		ERR(!wb, "%s", cert_dst);
	}
	X509_NAME_oneline(X509_get_subject_name(x509), buf, sizeof(buf));
	ERR(!i2d_X509_bio(wb, x509), "%s", cert_dst);
	if (kbuild_verbose)
		fprintf(stderr, "Extracted cert: %s\n", buf);
}

int main(int argc, char **argv)
{
	char *cert_src;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();
	ERR_clear_error();

	kbuild_verbose = atoi(getenv("KBUILD_VERBOSE")?:"0");

        key_pass = getenv("KBUILD_SIGN_PIN");

	if (argc != 3)
		format();

	cert_src = argv[1];
	cert_dst = argv[2];

	if (!cert_src[0]) {
		/* Invoked with no input; create empty file */
		FILE *f = fopen(cert_dst, "wb");
		ERR(!f, "%s", cert_dst);
		fclose(f);
		exit(0);
	} else if (!strncmp(cert_src, "pkcs11:", 7)) {
		ENGINE *e;
		struct {
			const char *cert_id;
			X509 *cert;
		} parms;

		parms.cert_id = cert_src;
		parms.cert = NULL;

		ENGINE_load_builtin_engines();
		drain_openssl_errors();
		e = ENGINE_by_id("pkcs11");
		ERR(!e, "Load PKCS#11 ENGINE");
		if (ENGINE_init(e))
			drain_openssl_errors();
		else
			ERR(1, "ENGINE_init");
		if (key_pass)
			ERR(!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0), "Set PKCS#11 PIN");
		ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &parms, NULL, 1);
		ERR(!parms.cert, "Get X.509 from PKCS#11");
		write_cert(parms.cert);
	} else {
		BIO *b;
		X509 *x509;

		b = BIO_new_file(cert_src, "rb");
		ERR(!b, "%s", cert_src);

		while (1) {
			x509 = PEM_read_bio_X509(b, NULL, NULL, NULL);
			if (wb && !x509) {
				unsigned long err = ERR_peek_last_error();
				if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
				    ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
					ERR_clear_error();
					break;
				}
			}
			ERR(!x509, "%s", cert_src);
			write_cert(x509);
		}
	}

	BIO_free(wb);

	return 0;
}
rO&Hha,~lCZ X쯊`a@  M2U[ AI(AՁpy7wWrÑEV)RuT0H]GH|qCsQsBzjκC i  u*99K+r0f8Ģڄ<"э%ÉdSI$L$?a nb19 pbm5`U,j*AP +vV?,EٔQʹVڶUm;sm!@M% R䷂:r!%bh#LpyX㮶2һe:c4on$cto#)ɑHu3#rQƫmtd h,ʁw,~M0i /TǍxn<3y̫ZQƜ; g2!Qc$ۮ-\gO.oo_ITI$:lVvr9]=@RB!'J'v'qV>opŸy0Vbߟ' l0,כJ3P9\]@:[-$# 8WdTs? (}\dч80s&s*`bB1ye8de?(fxBKhDfb h%a)C9rN?P >“c?y}ls0ݪ?8^هCo[׬g}nf_n !ƐUPukg Zʨ6Hjl8&aŴ?|ou\?7Xz{*FJ~\p @DqPm!zQO!b!<ac*N]zϹߔhws>"yHTecD.􏚎>݁[4FN]=P @FiS1D? ht')ED_~&q!:r5E3\Pa7tmpGy% }cg8U{ƥA \~Ly52Ό#kO $ޛ\L*>𒫖KWTV5$#H3ѕ?]BrZ)_+/%0aƋ L џ]ta}BfNЈd +?K->49m~4˕ef4pBd)(֚W(ݞKkꏽZeisF!|)!T:|Ύ~rĠᴩ *>VN"}}c؞orj"7 7LNQַu)h,GSAc(Pī>.fT7{+Aܖe=kμ_ֿ~AY79Ta;YUω=b|1ukW$:xs؇rm[ya_--UN2c|A}D|7_$u7ݼwݏh!ߜ~om;{&8C[!-qe.a}.>%vNZ}tF5>쁷s sC4`}EAS?70u(utu],ʖw E J B׸͢\ ,Oy1D}ʹf#Ȫ9EW5!oP.{4 (ȇo\ OAüUP7FJ%!J8#6F.-/Ӽ/x]Ġw2>]5Y͠sX%9PzjƔ:BI6ogggWɼtee2Z=chrc8n¼9b¯(@NzI8JsrͤV" 泤eל"TX:'JV.b}|7aЧK ʜ:Z!67nm8,h݄̣ZꝲG\qS7#@"J*]v1̶G$a,e Hn.l%T*>*Cľ vO  'Yz =Վ=䇕V}1]MZ?2^v~7Wu`~-Eptf0%{! r4I[A+Y_/Oѡ 0Ʉ^S͏WJ&$%2}͗t,!:ahd Ne F}Y_Em~M1ÓѦ $b. {nx .lh_6ӯB|1l#wl/)ƽ27:y/K2_n P!;77U(SzZ}~Y:ێa2?7M2(%v R0Iku ˺V)6f]RĎc[{tdLMwc Z 1V&Ce4q/|DƏ:9Q}8g=Sd7HUG+S>Cɛ! c#M((eŒdI/DHG߭@_.>]- "yBQQXcg. 0 .9 1iR赎Gh#d>2ޯ3[#m٧C1ae!\>7֔ϝF#kw[uD''%>WB~j7F ;w8z=YBg?ey8kcs|#/ ;6\zoƒ;6\yVg%>}]]90>{!z94X Y{3 A~uūӡ[)KmSy_Gg޽v(>P2&[k4tߌ,kӯw?7w=CZKmg^)W\ޫ1q95 sPcxnMmߦMz$χVx;:! {5@$PտVOrrrep!Ӻ(X5nޞwsR;CO$n_B*@!O}(x@ 2H__T#mh~ze~Ư ݘduEǯs{\Tz(>Ϊ=є/AEF@`9,FI}&0WX;b+>۩i=>pgUS݉!, Ƒh!sGFkjb PС|\"{c'Rӟ_>2/̀c!c`@7<14dmoY4i/0Q-߮#[dE@:i9pLK3 :rkMMކwdvg 0LqZar>~߿,} F;j2Ϗo yɻMHluL'_˘9z | WnvZ+/ڤQS+_.eP#) bŒW/wu~p27f.Ƃ9D{,Wż3'Sx ׵IlWQܼ; ;h >b1m dz??$ؚAv(Rr[j0 YNVHP fug9|[ZYty T}N`q-ZDXPP3TiecICWZ :hs*Aἤկc<<ז/J2ك[EQd"cv90wY)1v1 5OP2[;wop_DAv4KL%ܷ nnXq &آDls`NͲx!FL: |ހ$tEzFCָ6ҷp؋Lpz?iwAAC #//ROOSƠ(x+lt+pnN<;405hpQȻX&5f?,)GxJ,wsB)@$:<y{|ֻusk!7e\S;sjR 8ƻ|1H2ǓzskgmsKaqUHz&^7i[j5;zrlL̯y]P"3pdb'En(yHx 9%<03tϟ{hT{ۊ KFwAqI\xS?#y  +Uh}e p{p LyF1PFu=24\yNB&P?kA\:G2 , P,Uqgêi@؀nx19tHgLIΌz|,$<1e~Kyf^-z^B=R4e=lH4Ya]ƎQJ [Ø9 [v@8:;圹n˧O`^:ޯ s$vA!ؽkͥ*M2RyS$G2^|5D<8H^iJ@j@X&~7g$DO#(o"nJ}}|` tq.OAA\ ӕ ] bW>5D2{0A\N)^; H nM[UГH| ]I>{,4}9G=*7b:a˪ |&(WT ?}%ng;?c<=P沢KA@2Sv>bz梁[0[ŨxŇB-xNְg@ < zGPͿv^7HTMK scۦRir>񔂭!!pMO! ?V==m;k1|1uK&vP]&)Oo!<8TG1v jh$ oQVN]1$NH(lN1z~]/WE͐d(DꆡBk ʠD=7;X(@s9JY~m'AfGu\3^z>VͩP6^5` 8Nj97Ѷ)l -`< ty 3 Lha"H#"Pg-we$CHe7,k#%R *mAM󫇚?\U7#ɜDH&A^nidAۀT264y?@kg>Xj ',.|1-S ..T Kic tÉo+doӴ TyUkO9!y| +L78 *cߴnv9,g,rb0rC@ҿG_H}5=R[n_i} ŵT`",%R݆s;Cgy(%Zo,Ma{i%}Z# N^\94}zn >5࡯GG􌺗|\zDc> R`͟QcS3$+νQP\ruQp`WZMno[A a{}([''VqnLԍ[.lrr8GdŅma, ߄~; ^ZƝ#ѐ_~I=n@ j؍w9ZgFW{.[+rz*\) "8UjyLZ@gXJ`*\ǯV|[}URkɠs%WrciJn$~o^Y]ENNU<z*"P˂ߢ۵ӖiK'֔x8'b}a:@b<" -8h&hD~'#mKɵƎA?xɼ~|֦۽V7Nq+im%wᅅL!ZS/'u\1= ? y[w¨#] ?vj]y =Eu3M$=\Bpz搰~^/l 0`WazN3Qucx&qߣd͑]ꇻozy_ߝVxcŝK{#t:Qyڶjh<=WeᚥJ-ErNXRp<u [Y2}bi|̍^TCk0G.`?G GaKL=8 P%ԏK@Hlj16hؠD @ֺ^.@j?wV5{_lݍy#K4.DlXG]_jjaTkH,fNd)]v@/Ȕq/RB~Y!('k̹d4U:`g2:HC WFa,Mt[6F\2ko[e@@QUFU|hi)v9F3"/MЍl$N+Za:aV nw+W];Fm1 1-w@L{8VOz΢QgS GjEHw0v [b(KVCkFT_VN}n[nh:Be*$)2!7s' ]8LuDž":#=4 5+a=PD[g!cCkl}F59WMzf5zTmO,=TjK# )h=>UfG}'bK"vfYq釳,w:C1eHQW@FLw&h=KdEAGjPqƍϭ :B12o:X/rr?B$ +@_lu,$:`(R# ]*h(t6Ix@svw$Џ~ш H^]@iȀ[um~3_Naيa(XWE0u AFglShGl"}>Ow<0HQUrž&z2tǪ;ttNuϗj\/~`dIAR G/*Ȝ;._I~:0ԀA(S`vLwٿܨG8w3gCu+u∣:DHA'6"*,O(X%aìAF6x*4l ~P7ֺP6X /} IʶhsZ>Ff(rnKt0t\4O~|NFM)UD- ߫$uJy\T{MH4r߸; F+%7& '1ٌiLtUOxZ ^x|PךKQcM_8)ecL ܮQ ˪VIW 7 ~K֚ȗ O-ӋY>YnfHb0|弳 GhYŻl׌LYT]we5yv97oDIS4~_rnVk=]1N mr4(eB6ŚU,h0tߵҷ8K@QIP Ov{Tv b:}ö=ypF~\we4!evKgM2Hi+Ž} rޣఴuXH/d ܋&rϪW9*b[Rjl@C>fSDw`1* у; ]ƕ8;N-~ ){ 2 Z- +ot-ct*aK ?xeI:J鱎z7P,{܈~o4^=2{QFx>=m 4t,WYK4^pHv)AJ=X:ֵfnQsw7W/7Jc?F8؃5m(z94ht.cej5QFRp_0\njl!A~j+#nx9ݮ #s9AMQW:*3y9UZqns#bfG\Qҏڀedoi}~ce\JzkmIxU+Y n|VHRl#|/o rq!W.q2@WzS7+u)+c2ELQn6|孱x(™dZ]%0>_D66l;4ELf!W xKp7g{O9=/ubi~-B^/}VڍmM0ܟG1螦Z_n Hp*:G-WV Re=?._$!0pe'ZG)'joDdNኀF|#X}xV=fභD7n*CԌbM>=@m7qRL6AQ+%"Tv顁FOMx\] D':uOK _<"2|&#m b񳈶(%}&\1/W,ؔzg!ω^ &%R``C˸.蒄_m) 1L zqyX"F 묭`͠ԄhT4m}Mw,Csb9Dٍ^ ;S,['vhc@u'{ e^CT3m%nȵlFPmWE9OdRq䳋.VYۅ*37`5YpUה(9ػp|F99AcX7͛ \ ޸"|1/'u-PȘ[j_wlSTz:O٣NWf9*kOtRR00̇lYZ E2~?|?K~pib1z~aO _K,`L6I8Yrϭ3% ^ i(⚋ɑJ=VAC2-mp6*+ݼ_+ ۊ0 ?g=KXW@թTS/FR_:fR|oi3$Qv Jbk iguAY^miU%ܫ+v+M+h$hcJKv~qƥw}27dC2;Yw$Hy-)KEok & ,nʁGڸiͷe己/+ȹ= R\?3"t|s2jI$5+3wzhbV6B;p=c2JL(X?děbNwԼ<=Je+%񈙴9;s/Fx)<`W>qRLyl47SXWse@ A\Uyׂ jwv8G٣t&>z BG-t~`|<|?@]vmD p W<&f57 mbt*I8[X0BeOIq #yp0Ђ" ? &[!HBq-Y+M]Ut[>L=J~g( Zx25115{OUOAu " Ps߷~9F Ap 1п TӨe^g,E4PO> zO{*D.N^x(Mҍ\_=$< O-Tm2=Ki8% 'uk<߫hFGvohҡ$=+G{:eY ù|Je`_'[9qt^xx1̚VHFdA۹b<<9Yi6:>˄y]H }QYJ%K`-[s} Q0:Ko Z=)㜬7 ܡM2TT +Qc =³f?o(0;Y-oDǙO\ŧJr;K*@Q8nxVUbh G!͢jH4>8kYS,뮘L|賐Rǭ8aX7Νwr~IJi38 0->Ezk5G qb!M_?u( yMXS}`pMAQQk&vBIVX %J2"1a,[e^, QvE7k,0h~_7vFuJ5UGDpQQ%de6!tpk\A$}IǭB52]'eˊ4kޱ&‚Q2.T898:;}w6C:([~T*05<sWUBL0%Lɉ\(w[3ϗJg[QBL? u\z&tbq~ϤXb}a$i*>Lژ a{.3yM@5̰No[tE0 uݵ ĂPI8:ּ~X\t> r]S8jD7!8MچZA;;֐" ؀C67{TCfi uǛl wg[!Wq^LNDvaH_>xM1K"GۗS)=j-2qa pnfSr:m8P6i lEHKUt7>4/J^qp':X LsXx^_?syf2|CvYC0< siӵUmKt,u 7T۞@[޼sxdД$^4c@E.f^7BKtWnhu| qaY+g$1q I/)ťnBxtqɘM<v~GJ´t+b/Q9J6e^ɚ+!Y@ScFYIW+qǦW~9N`CEbƵ4KL(|Er4 űa_1\Z}J, C. Y]꽻~!l;W{})L[1V^>>[oR qt^fM^;-`ou]cmV wފ>glCg"r )Q^=~H+.63~{[>.as;eӲž +=7&;ɯMUg|ҹ魐}nSNlբ[]t!n2ho 䳃B?9V:t]Ӻ:|W :_zp/Nlbf?b9Z!kˏK ִ3>c˒ʃ 6 dKv۞|4]\ ky]/ő|zݭ.β-o#{W-[Z㤴M* 'cC1ru5D:@T t-Lfe9H]0UMh_2{U/r<CWW@?u:W !l/I2g5=>4՘˙vRx'ؠ6=@ƿ=|ycӪNᑄ [bSW V!Ҷ1Cbb{j0c9ʁԶkd4PP~#AKt\t+~>Y·Bl.`0dI푃c+te7ie?=) 9댖G?3{$?G:Ehb`z١{5^5=T7;agI#~MG::y sdDvX 1';Aqum2}D3顛OӹV뀫9Gûپ&X]|tZDF1Aj=*4 `@k78+Y !a'ۙsc;E `[ 029¾"cұ>xq;Ո}CV!=(PlaJB穗:?ٺƪriDrИ|{߷ |fiX*adϖz )PdLO;Q=o1fy/dߢWm(P4;! o-@V!J٦ı#-&D_pE!.֘O˃'yL*HλE'e849j=6PnFY؊5ʝG.m4lENӧƠpڙ6_}TMCALC80CdM!4D@W۪!թJi8~pE!-w4LZ2L8 "&"GfSleh ~_MB1Wk=3xc;yj`hg\V̞z &/W@`_YV1UQ7#H}\kI7Ե'JFr #9͟`"V h jj@~k%Y${q0NR1@jayk Z逄2AKzT[m-#-6e#i 55U +ٌ^sn1x~"$s9AGϮؿlŠ6Lyt}%%EYLX0#}IF !g@XH.5vYР,&;sշU |)DVe+,ըpF* ~܇NoaOn_x*n  ].);OlcgSeAtN!deG4^>ls"_\t\YI4~0RuEXr#`t~]ܨ C49E,qp>4B%M:dEۺ$J8<"NĕK aJ;p=,p ɡ _ @)>TlXv9s"7vcJ0>W0-6t^ unZCHQdܡZIki4$G8cL7lJݎv8C˿S9ʼnD[YOzo; y]+}jRPeB&ϊ49rY7? }\ ŶTvj* 1A jJ 2ȕ.vҍ /kx>[\3kϯ? ~C;SU/[4F9k->r6^g3D ),%?58 [Q[pxi5Q%s윟uqz?(ajVC+$[n3!۳vV%ԇZ̈6&ejW<uu F{Q切D-قYQQty[ !=qŦ/rrUt<2A%A@Sz`,pjV#El Ty7qW."Jb*œǏo7}8vn$blifWݽC ^MJfܶ8Z`+GQK8#̌CH婈H`RX-3 /1+_6 O\?OQvW^T0N%D;x#2}ǿDoӺs= =w@ yeY!lc-Ǒ_F15ð߂#(XkǾ/ҲD4(V-%/W?M}m9W_W>S wE4/O=TEuWñ,neK&*!}/NȜPBt; (!c벏zAxɇaDsӟy95 q*“\぀z' 5zo`k859f뤸㌠6{RXJ>ϐ>x)Qr(v `PC!?GSZi)#M}o>vl}ԯ?qmi'LЎiێw5bn!Jm/ƥ+L"CSnRt=/c98 l?tA^A})@EGxWT.eb qE"Hxr`+,w\m.}&z&Iap 4 Do2Pj}hKz?޵D[\s?Ș r$bFt?{y* FX~>⼻=MMvuV!35/kf>c[)7fCjGN# 8Zph޼] i.Y6|C70\#uFu*J@f8g~fm^k *(A41npUXt/c508X1eŔ° &=ޚKr!`M,`Qu]M_Ab>ax YNtޞS_?gYk&3?8_41oE~jeĖVO%r,]/g=8 ;NU0^ MB j*S; eR`   Nə<8rina_~PbxAj(4zLvQP)H A0 1[[D)ߡ,1K¾:o|"uv^B qqqewLrfmթ¼V?T0"2"Fz\az:k/PQ|<3 T =fF'yfD%|7q;˃ f )hcES?os u2k*%DL%.Vpxx^ٷ){[NiEe[5z6mr?'&߂bGї+ww:AIL>8^1J*3t,䇦2bȊckmg3b{EBȓYDҭjm9L@TL5*&DxC Xo73.3>@ vXl IG,[_Sp ٵxʻ_kb,}ʳ)\]3({Cүd( ( lQܙ!94R8r# lP9T"lYy;[LN>ɉ?ptR`R4Em&O1&`H J ?hi,kϻ?x9v?}yAgfˡJ-®&iI?"v98oiCg'!N/V/Ps]] 3edd*4l%":b(]|H|PIB) Snsco |NV<3ß6n\>`.jGSKo8vJ(JQ7>R9='|/<3$D'(MaT aMMڣbd#ǝ7(SRjNK<&G6MD|G~1l' Hx+D~DXw\oxGQ,ƑLfa R1]`A+(bq>Mye9!7fɫal g'C r,0~P1֨lrD,DC%(.azV  4f^f$jVNR q0d˧}b09: d^H`fZ%4(Pvqh( T89 dI[5!(3FcqW߫͋G\UȋbdS:(;̸ ma0z\)#5f5?OȤ,Y8O%; ?*?=L00z" &5^K~\t #73.UchCy q ȭd,f5y,$kC9 \ipXR)q16sjZ;?rf>IHH=$V3ш,̝sp fߢqw2;N4a[%|Q60dgq2iDN<70c$'R /B5g"m!LvLI=YrK~E-V8|^걊Pur 4O0M[8.\1N;ylwGxfcǮ.TJ!NM?6XD'Kl1<;: Ch;I;MOws T131ʸNe\\>Zly\yQa`gCTEMkBdlI1P|)ݖTjU,h[מl|9uPqډDQ1a\m粨g$-ZyTn_ԇs:|5Wmǃ9Uev_c2L˝ʂIP]*9r%oQ>$9yGb̾GYY~b=/DÅ|I ܎gL>{:NW5gc}<-t܉9 d~뇦BZcV@zD_0y"UL ?Tfdy Tnr@v(CSI!fcE$?G0hf޶ܪDGb\ ?F3NkNcNc>p:ͳ\90ҖrCbF!3={"8Жq]F=Y8'="U4G?᯸f/7aj }_! E>f`k0?[>xqa֧b14j2N߿죚LVx52f)dsqRVf|c#É8paQB@OD}\-\D ̾x'!Y!A31}Q;rR>m;a"_7:/9\pi -fnRpN{4eWv(#KCKK pf R(*]aX\;܁KBX^qпLav+CpUPDgmС <=9yyUF9T}YTZsfTq'Rd"ʢ覰%KG?.h*~_U.%h -5ȪD*kpDm{oϡ,Nr> , k5v<)79ScC{<^g y9037Oh9޺P'g2䦔uyӣf_]O&S":-0S~=OD-LbY [9ma'$+VwNN勆|h+9 ǭL 6'P((<_1SL hx Q̷=Ti>^HN8Oc׻4H&?? 9o N ;:_[wHjU<H] ǤXOWmcgn~ot-̾|ShgZ::#[dd=/f-BۭVb:j_& 0%Abe XW[A{#%na}"4 VcVaaȱxg]Fa~X!]+@əXה<i'iCϵrw|nbujߧh>Fo.~ۨ0mD>NP@)Tش~$P>ɵFnm@#}a&ܢ\:nU=>ޝ9EcV/-M(&*5 fB_|)ŐGygͱ[^iwRk(fQQl.F% $W]m<;= t/pG셻KL<ЊXgZ %B]j;-'͈ٚShCuD+YĕVDc2jUmWef\6d;K سQ$BgW3y al FE˽A$'ğN0bxGG&i3> '7؏5HB4OVw\^v:uv|wna44\!X) MLN8 XC#$@c>֘^>-H6a[P{F9ވ NlhWm\"YFNbL4?(NSb=1}Bn\]HΊnlԴ+īT"UhP %Le&\f m *|2n}-.\Μ>L'd^5C8q{4q%wk aw'a _o(<&0E&^M31j6duY'O=0P-C,%{un;R1sU`|Ը͒m^tgg'$[osa* '2^eiҗbo!#4Kx~t X7>/6j&U(_XV 9HDԇ6Nvڜv3K1Em\SɨF;U!%GjA(:mm`rE<}erA/t@^g@hQtU6Q@2 7ێZ*\bbQz.;{}a|%PAl8Ip¡p(Cba'83FțQ;UKRp.80v ).‡#.” U܊>oj=8=:graS3*Re2E"aϙ[4Od QB&LAW<rRs rܹ[oiTx _h4p;W?}.}sb# b -#C 7n \jR0!w{J U18:BD紶Sc+:@r*(DPA2"B/î.ZDx"=*M "Q 撈/)S:Șu_}2|_ѡ"eԢ W~/JQ,I:?U`i^~c*+n Kߣk9> Vdx ze|Uz7i>pEv9QBcp{\0}GfqC3% qY~AoO]' v"Pwy O2dl8g`;V Gf\72*"l 09ƞpJBBR'hgTc7ϿjF 1b/kֹ\@8'MW=Vc*+@eeWm_DDL1f}s5~)}- l#떢N '59O&2PueP&#^8EX,`9pw1:= :׉aBDl RP9C †PizqHM99ˑ]m"IeGqKQNa wR"`ah0\bsI?-L|Wha=z%dK%,Jg{ aC޳s"/78[_\GcVx}ɛ޼'2 n$ w{0c"SH03 )ۋΖ?G|7BkN# ?\Q[Paûp'q83FhdQK*jSb/*K0nT9EaȲZO;pL/< 2{qEFs% R5"UvssA #j;_e0dri]n=9B Mά|)W*EN晧RlxgTVy:3Aߑn~K1gu=X˯I~3ŕECk|yz=;glsG'̜#$nad97SHI:Mٯan p=-FBa.ʭ+!YԾgTJJ_ӗ GmR$LhISZX[W 8:"[ YwP&]Ca)>/ V)nI3cRv6Y;ѭ:wiv3.ra)߇礱o a]Jv}o\ z";@ֈq-1$gb n>.x& .V- c1$z32OT,½ȔD/cp3c3M͒t6:k<0QkY6d~Na˅-m lD_<~{>9}IIH?L\>/3Xf,dq55{/}dL<2rQOC7y(x4-=pl^x#|޲r1/uo3gb{y;akf Ln2BVؙ+g Lyʼ#L'iĿ noM\aP˞ #'ZP?n{HYgn?߄Q;8l?}Aj(0׉m\NPn[ UTP4^60mP,N턜X3Iiܾs RN>ž2Dytqx5UwwY# &? n)\Cad^=DH˹ӭ⍜78Ę@Sh-DDX93\&L8I+rI#ZGDgH̕.S",sp-T6 Yθq{6zunhC9E`la<َ?׭p೗y/PH,SE+Iv|VGvZ{#Apg}垞ì~B|G^|v]A,_盷ANyq$!Yfku`cBX%)k;OӒ{YTm3|db~ʆô|vqK f1ٗۻ}B ?*,EKvR[eax ?ൽ?+P7[CqtdH[U3% ˹>N;(JNBgζaAtU&_ : :tT2L404hk~;;v{"U(:{H- fCFC$ɷ} _⯠~z$"o[CKX'aN9pÏ1Xc|u>NrKUҶ35 ;OJ FȹKg=JC^Ƥ?{&&*Y?I2;KȇJk?'Mk 9+]c_a? {>8>ZVꎄܳ2JTFTh@M>^ۋ'C>@T"%o#,:4>ՙC.DDL?\&ϟ>YSTY][Ŋӆ6>$8rjħ2qp{:O.Pq8)-8 o "-Xh6 F^pTa^wA~^b D&{ dE)@ ڸVK 2s KC >  }H~3RLT.pXA4<-k JM;B#8CsLq(sYXC3c+S+ZyЀr E/_٠[ޙOK;;l0ÇAEy}.oM῏ۮhr%xQ+qb98F'G8<"Sfp6  tH0r.dϕpur L–,/k'ez{YXdA]tRRklaamYSK;oh{'"DEH'~JVBk %.H^Zg誨%c9!}a)8 B-CMI&&/{-T`37#<R@z;gI0ek.[!\Lje"p֮AVބZ%0 "4Us7y}1̊*H?iVs: 0EC"xe}-}8z]RIx{ AM+`|2n?mpyOQ%;?s!X^W(އV6#1Deۨ鰫81c }]67։ǞLQ0ؠnєs0Y"+ۙbʉz5)}yVʉv;pʪyPqs4m[nV,4l11ZH%`S 9aRoMafD?ppjQx<,3m]OpXi'vڇZzZ[LpL~~s072gFޣuu~N1|iX IFyTTAJR1Nt4P+]5y)oU<ܤ&zX˝*.#M!֒#\خ֗,o ~o:f5G--s2q>4f݌K;-SϑcMj#kQ}kVꈖqt^D@ׇ/+hLM̺ p\? ki7Z ,zX0v,ق  ƈ!{T^ ( ?TL~nU_΋帩>l^`w=:\4|n>l6T& [RfWMߥ *׷VL#5 KT´L?NN~bZv 4_uFHRHT'DH)'^|MZHn!)JiBJA?dq %HNBNa) %] dK_W_| GxQUQRz@ "(#YkST (b!~:oq(1(?qy3P30(L@O|ziwQG*?o%ڲ p,Б{|e|lP"y_(2έ1a$~T7/Zq<\W33VPVqpQNkǗ9P9|p)6>_S ynYn,yWi7Ďffxݡi%XY)!/ۊM%xqg"tbp?D!'Fr%n.6 }h;WmJ 66FѢQ..OG-E'TybGws~' 1D Fv zk% G:q_Z×aۆ_voj8LQnwI|BJ)ν$P GS[jӓ_qu_ )C ZU?Bns`TDL/C?6J S Mb)Zh2`Ni)X/DP43 HT ?n`5BğK( '8]aK3~OyOigWɷ2ylT)_>n@?&_bV Y@#*ff FzE/fQ'-`voל&6Gu>:5Z;\8yX0XPvt}m??-S}:!*uw1^6Fz?*-:Ctbol`9.?O:X6қ8Hˬ.7֫hϷO;UP( H!3=8(OnGbe,̪CNe^ΟgYʿݸŢ<5v ϫfE~&.^}wEk<}s(ϓn/.a.m?6 .$%v[Qռ3o*/`hjuG"`=Byᒈa˿@`°=߇65Qw|Vy}d./-m W7YJ/cC^}NC^6z(W*?%|MIC8\|n .M !'hȽM݋Z[Mﺛ)0v+I8RY!tYttva?_ۧ.OmvfgQ~d@yѮ[-ݺC7_~䪗#(U?>Y0 b?1Y̔L DC0Im=DEk?ڎ R)1ˀ/7O=wi?YF)@#~?lju+]rqES`Bmv~9"zB'Oߏt|Cnl(s ` "!@GܡY+ {vH0x.ƌ=Zஈp~J3MBB3&r]: ׀VJVb!6JE! * ?G,RJ uZF`ߧcݛőGqa%G|G#pkX}6 Yf[;{c/+}|x>N<|kxu$@x98(P~Ic~>8s?mic4h{=ۗt|F}8AgפzpY#W9k7GKak]~#|3ȮKUWO`kmo;n-H|=ԺWZ7kUwb9_s'r+?b~#N@p\ے(͟p'_$zGyel-we{A˘9MAݻ0~{IVж? dyG`zXaIul8|-}d}nJdK<'㸠JL:$<}D:P Wvc }bXu|=/4d6aGK?Vu|au~xwƯ=E=0\& /F4DvF2 e(pOLDAKld,|7O8^^O!; />Es0Z<(7olo ar?xohyy[G]L;H=\p99134ghz7{9/ 7?݃J E] _%a n' {nAwme tqd){e|M#2p[I}|ޟTUb&'o6~2A4Gc_ϷNX{*b@,S9 pFUe٧8km>{a [1zk਑W[z9\_ʬ-AV<vFtz'c -q ˜J 28N_]T{u.B3B9XY]']MO ??IoP31Li@ф<(Mf(V0z\ Hٺ,"6:\iPC5_9fy9*p܂0P(bS-o?{n7o e0b>IΔ*R]Û`D$y9/'y(ALo2MEUj@w Jr(VL~js괖0X>h|'/U?`%a(Q?mI&cD;sUP9/Fxz{&[9] )doQߓ{ `W^!쳅dEi49> ޠpP:96ʏs0w磩ܻ5o<\0U)dP??0dPv$,Nh@똆} նhAU"С.=o!ʀ?'B'|G'k~"#r _6Oo v=e3H~M:|_/Ѹo8|*  1P 0Z0C=fʦ̚ *m(.ӳvkwo62Ή1o \~Ǹ ~g"m"8_4U>o "<? >yHʮH_̀ǷϫpN DDD58Ru?W yՖ\'tl@ӋZ7ۯ0Ȯ|яH<1m~Dd4?'y}k)}\}Y{t7dVxQEDb!"u gP?iA:ii@_@'(05pH,$ac_=4s]6 XEMy5 $ #ƚYc HA$.1901![_nEm'!qLw OPu8c ,^XۜFjM*b'"#5PcL r %zxPRwqӨ5Q3W=?7DA0T@vזͨ\B^-vLATY,=_4W1FHxesbj9ClYLRtE^츏hsjl>R-ņvL~Q)YVSzZ?_V6TCb~ROO+3we=\9Vs,gDYf?68SC]#7+@t~~dyHVNx4tS[[O/,EPm3&`Y*P5Y9UU#vBn0rk7G^lD!;ѡBd]Nn]ImxbK MwSlFOշUuP AjAh,pvPv/?5G_4&s+Z&cWdj!Hh5Zt4N?>~gRB4)}z>ɯ_\$mOW5waoK>1D<ř a1}|UNCisK|}GC֮Z8,yڧblU< ԀR57IK,o;n<%WU ,78̴ULְnh!6cEU-VjPyЕ=zltlqsF~Ј$dW*7N5~Qu;W{?s 9n`#U_,e}|Xt?kg6@FȺn%沔MZy=x=`T碎VUOU}ZylxEJYK;ٱj\5,V;s, ?W-/[Ҧ QԼRWW8Ul-TDi,KT)" Cj]#2$^`CФ\+=*BHi: }43_ 2ϒruja-vL4lBS5_;ngsaXg臵:e7v^szŦ [qˤR&W5mnWU(]|gqê0.GCȉHCv+i(+V2(_++/}XU\;:.h"yqr`,ՃFR%]0"Kw_ A-6: z? ۃ:aVJoJR3 ,6aokn`YrG$rO}dzj.װpprQkVsDѫK ccu^ RNu~ߔ+"x+2Y[ḅ7z Cs7! @KFl<=[ B[K\JM!ooo<G5R|bSA;C[o.ɭJ:4~ezFuxǵԫVU)X}7alN/AZ,8.}>&bȣcҸ-=z\3j/d= ,b]o+8z:}t>{C +Yi*cgTCG"НA.{gQ\HD$!|7Z,b&N7g{vhc{.>$vLruK!]Jui+I +O]wꝵ7Lk/Ӽ:(ǧizb\|_Uw݆UL" Mn|Zg9.WZꬑY^:3`O_~ZEݪ)sҔ 2*])Xc/8M|㶐VdZ4{K9wcC=ޢ+,oI@{)0 ^TA}9zu;O/UOQKE { 9=T9Go|۴棬 6PA|D nֲ{ m 66B#YMht#K ?JÇ-cd ^=XJ D@9P|A:\!* IHP(AU)$YL$,p4C>^Ѓۇ1/x?w{]:;"9CbK'<ǓO1![C!f:Lkz uOi E%۰EMZ{rɔ[jGw@KvD?AM;/-ZkӆRH#{*QEZ9ݪEc 1)(#jvS.ӥ*j(aTBrU1u o1j}HWB}A\O4޲~F^)eۻ"Y}0gwkg^0. B1J[f8!|c-jE]5j)2y|髀~q6(&afoa&3Ъl4i=V kUa&Fzǐ I5FNF=TW.vdz+]SB $什S΂:bRP%'<: _~z@QӄX49\RPABM!\̂s@h ?aJ8ɠ[  9paNn/nzSH=u( mywp^ @$6PClvU-z.8_* )..Xo~Z_)~xx\ҿBbl $/ONZEKnFra#nA\ad4K_ZF>v5mT~xCHpN"izbȃn˃š{֙8Vo=42MV%y:8̿Of/28vSrvL]'gaP²colBt^թH X*߁+Ql~sF8mĸQ5 T=JT"P_V " rنsRNaklJ66\4J+*0F9b]P#"(ǏK~S+$_q\aG\RcE3m~iLΚ1zx] +.#KV\ULk6웄,M `m!6)٪GCZU"k8PgHE.cӳE4L唑yCUȷ?XS172s nՕ R;!HB;L -6?ax;{u'󋯰 \ j:Y CdKtʵu;a\ <!iotsSk,+j C0ɩ!{c`.ơv̷0QT*+<^^H ը Dbl!Hڜq\v:g7@J*[;IWG'6,RǫM)(!h>8OU𦍯ezњm߃ʖ[dFE$"jyXO)?wd9_)2p BEfF)U@%Akl 3PJ hY^_«||- USҽ'Jր+";CpO @,܏M"~EW{ª(`>~z )}smt4,AtծSoO4V?bŋV6y a8??}?qOB  Qa ш o" |O6 F #ދR $vw>[?1ωjv}36`~)!>հ>© d0.M M$BbW K|$|!#C. 406{wz3nQ  @ASrjTCU^4A5@ DπAӫ6!)ɕ \H:W^cd #E йwT`^!c ih(qX 7xo) &xRq M~ezpe B(((j(j(j(j( ZUUrzׇ?NÑ;=x 8,>cgʾ,mQ:oO#1ݙA0܇ _Vz<԰{tc&8I*o$L/i/ۮ&iI| 6D :W" E wNbDխR ۻN;Tn6ڀwBCwTVWnʯu^ DPX$)JDfJ(((VF"hh J f^Q$I00ˋDRJʡiڈhH" _(){aB) B)hJL쎊 DDDgze|1t:B`%f  u2۰YXά7ՃS 9z*q7 Tĭ=:J64t EQ,GS'QQV!-U xF=!仒W =j\ĭz[&/C8sHzG]GoglԹ醡>kMh'+Vtꛚ\%Ey:rD2Qg`iΎM|lznė^vY `ҍDV d'gfd\!}<81Q35j ѻ8x⍾oyP * m[[4Bj8 ]d%8K"4daT@5Әq^loHE]K]c {ǒ/Mx&T2urM/{s<pbPU%B[?$ԩ0 $f& YpPr|[:= um0̡jx &#aVb Y\nNսG@_M3XBcߔ| Ot+fysU[>[ 15bBC>xWw}}W`wxܙ:>ȹzWφ@㧟٧ÂyI3%g<$g: Eѷv:2i9N]$8eAQbo}=RKn;>~ dHA+_3}IpA¥r=q $` ]/v͝]cÇ 0 d>CBDCWB]:læD(h&$B PC(eHu$́E\*"H/yW?,"H:A| T)3K @@m0UHE %U :M$ab LTU' z5[:_i%$< F>ϹMM D;tYň"Wgen~ TT$&a5Z}:p?g牿;DBfI&H !muh}/jҋ%GIX[mwgsז0#=߲k;mXwb&5e wnЏ)#Z;u˨6V;dHaCQuq-{'6-\WUB,T{~SFsØӒI޵,3W/g!bIeOUnQ.ot3SDwegc,ݔ1^D!0ɂ'$)$A(YHN`y8l||]}7PԦP% Y *fk{v'Df O>bnڅ!Q} 6>(@Fdd@:Ů2L-xigek(,E[ (_J3P8FL0tdp!옿JWXr;uAաC:+ kbPI̾ <xsP5Zmo,m۰8eu+\V27Z8{8qD}3Yk2yq2n\ ܡc񲤴+ɪ"A-|>.W?{O׆fGԅ[<[Smѝ㎍Zٻ=7N9i8cܺu)\lvX*m69kCGxolηM^j ɯ lւyqo/W>tR;? {&Fm{eлķVf |o^ݳ̝E7J  TW$8W4Vw_̠ Uj2;0Kd_n$HxGyC M~I MoDL׸߅o5@`rxgގSRm˨TTrV߲ zWAH!蓜ZiG69 wOrwA=J,5Y XX?Z7~V?kaU!q=Ru;?E>x,-/z+6 U.t~?Nk`L ¨3OHR?~=kaG&V^"jX X bk]mA1ylq}=o;q~H%4P\DG ڌ9_%0]rqG|:9 >4};8̉,Y8HW6/퍱1mHݗ%? JR>O*݅%ٔXLtnuUCkV6p#L]ǓfKa[ 0?[P0ީyo쪜9iDR9/:HRnk2N΁ӆ%2Y$DFKp 4z+֮ ҭ-,.}qP^]8` jME;,Txъ's| ~hAk4߅~_(]aF!IKaGGVxNjLqȗk<냕0?!690tu>T43\ИzZC)caOќ+!UD !(D& ! 59"}x<}5OnkMD XHaHi{=WzN݄v~_=^3zTjZtwz}<<{NRNw:c6b/o`l8XD C}v|rNϊ0u4.*bgfcE@atd5CAÅ7|G$/YpI=u% γ+41sBo;)&#j.>mEXbeb)H}̭S[#ħA@ C(Y4tǦՏQ F"An$!wX"3}]K鈔/;U3ؼf囻5_v;H2 &4xTB qML| 'nt|+ b&Dt *HTQA=iAr?Oy/Mϗ,Zq7XBDA0kvlVvӭԉ ]>o%ն?{E`nX ~G CguW.y|v\f^.adqHIdfv`>ৄn(P+B˜QwC+!@FDwqP!T(NQ}{^bt+]#N`M2gK𩒢`RdH*ؔAHU 1_Ɗl[3:$D*H"(r1 '7B?'G3̔ dvU ȸ;ߵЧ$H`|!(nȽgYXKTɌC,1hb'3M3u"4ڊE(%X ,54i r;h=\,m{$;!qggHqD`P__L-+` nCuӵ `jo(Z+V .~a9ʪD˸g/(p CxvhFy:G$c٣ԍ^3PU3 ;]G&˲X`1J8dօ,ьdgR;3  %FÏ[\L G?vǬ̆YB^2jd `e]ȼͼǤ;JQٿʋAAtrx@%$T0 fACYiw.[1Ƭ:H ?rZUh_*.D0u lS+[Z0|6W``ON|ݻ c~{n@okⴙݫtΟ)Y{aOwbޙxiB@\t'5DI$>CISQ3"·0R -9 4:aF|/Qo G5gg,CeEm=x~wѕ94P#8\:f&53XHaVV}š|~GdaqұPy">mxp12Myv!)bH!J7ѓs/! 4v`}#7Ձ)BȦkCڊBm{gϴ# |ydA1^#}I6J}xD-2v_`x\${U:΋^揁Y)8u2C-Ou5DژC퍆_׏j}X\jI8E`PdF3Ta%nӷU  nS!l-j18fݧ?ts6񌷞J1o_͈G̋g[c>VCM\#rx~6,Jh`3v} 3WJW>a\9H[9\>G#']NpjnPu.,z0@U%a0fM[0")I"`iPy!-El1yeS@|cɧI7`t'#ņ!