Compare commits

..

7 Commits

14 changed files with 164 additions and 300 deletions

View File

@@ -1,25 +0,0 @@
name: Java CI
on: [push]
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: build with script
run: ./build.sh
- name: Upload I2P-${{ github.sha }}.dmg
uses: actions/upload-artifact@v4
with:
name: I2P-${{ github.sha }}.dmg
path: I2P-1.0.dmg

View File

@@ -1,79 +0,0 @@
name: Release
#on: [push]
on:
push:
# Sequence of patterns matched against refs/tags
tags:
- 'i2p-mac-*.*.*' # Release 1.2.3
- 'i2p-mac-*.*.*-*' # Release 1.2.3
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: |
docs/RELEASE.md
sparse-checkout-cone-mode: false
- name: sleep 15 minutes
run: |
echo "sleeping 15 minutes to wait for artifacts"
sleep 1m
echo "sleeping 14 minutes to wait for artifacts"
sleep 1m
echo "sleeping 13 minutes to wait for artifacts"
sleep 1m
echo "sleeping 12 minutes to wait for artifacts"
sleep 1m
echo "sleeping 11 minutes to wait for artifacts"
sleep 1m
echo "sleeping 10 minutes to wait for artifacts"
sleep 1m
echo "sleeping 9 minutes to wait for artifacts"
sleep 1m
echo "sleeping 8 minutes to wait for artifacts"
sleep 1m
echo "sleeping 7 minutes to wait for artifacts"
sleep 1m
echo "sleeping 6 minutes to wait for artifacts"
sleep 1m
echo "sleeping 5 minutes to wait for artifacts"
sleep 1m
echo "sleeping 4 minutes to wait for artifacts"
sleep 1m
echo "sleeping 3 minutes to wait for artifacts"
sleep 1m
echo "sleeping 2 minutes to wait for artifacts"
sleep 1m
echo "sleeping 1 minutes to wait for artifacts"
sleep 1m
- name: Download artifacts
id: download-artifact
uses: dawidd6/action-download-artifact@v3
with:
skip_unpack: true
workflow: ant.yml
if_no_artifact_found: fail
# remove .zip file extension
- run: for f in *.zip; do unzip "$f"; rm "$f"; done
- run: echo "" | tee -a docs/RELEASE.md
- run: echo "## Checksums" | tee -a docs/RELEASE.md
- run: echo "" | tee -a docs/RELEASE.md
- run: echo '```' | tee -a docs/RELEASE.md
- run: sha256sum * | tee -a docs/RELEASE.md
- run: echo '```' | tee -a docs/RELEASE.md
- run: echo "" | tee -a docs/RELEASE.md
- run: echo '```' | tee -a docs/RELEASE.md
- run: file * | tee -a docs/RELEASE.md
- run: echo '```' | tee -a docs/RELEASE.md
- run: echo "" | tee -a docs/RELEASE.md
- name: Upload artifacts
uses: ncipollo/release-action@v1
with:
artifacts: "*"
bodyFile: "docs/RELEASE.md"

View File

@@ -4,19 +4,6 @@ Building an I2P Easy-Install Bundle for Mac
This documents building the I2P Easy-Install for Mac end-to-end, including the
set up, configuration, and maintenance of a build environment.
Signed Builds
-------------
In order to carry out a signed build which can be submitted to Apple for
notarization and re-distribution, set the following environment variables:
```
export I2P_SIGNER=(The sha256 fingerprint of the developer signing cert)
export I2P_CODE_SIGNER=(The sha256 fingerprint of the developer signing cert)
export I2P_SIGNER_USERPHRASE=(The sha256 fingerprint of the developer signing cert)
```
Setting up a Java SDK manager
-----------------------------
@@ -85,7 +72,6 @@ In order to configure your release environment, you must set the following
environment variables:
- `I2P_SIGNER` should be the [Apple Developer ID of the signer](https://developer.apple.com/support/developer-id/)
- `I2P_CODE_SIGNER` should be the Apple Developer ID for Code Signing of the signer(Usually find this with `security find-identity -v -p codesigning`)
- `I2P_VERSION` should be the version of the I2P router that you want to use
- `I2P_BUILD_NUMBER` should be an integer greater than `0`.
@@ -94,10 +80,10 @@ Ensure you have a copy of `i2p.i2p` checked out adjacent to the
building the jpackage, run the following command:
```sh
git clone https://i2pgit.org/i2p-hackers/i2p.i2p "i2p.i2p-jpackage-mac"
git clone https://i2pgit.org/i2p-hackers/i2p.i2p
```
Change to the `i2p.i2p-jpackage-mac` directory and check out the release branch you want to
Change to the `i2p.i2p` directory and check out the release branch you want to
build a package for, e.g. `i2p-1.9.0`
```sh

View File

@@ -1,29 +0,0 @@
# Notarization
1. You need an "app-specific password" which you can create at https://appleid.apple.com
2. Execute
```
xcrun notarytool store-credentials "$AC_PASSWORD"
--apple-id "$AC_USERNAME"
--team-id "$WWDRTeamID"
--password "$secret_2FA_password"
```
- In this example command:
- `AC_PASSWORD` is the name of the credentials config.
- `AC_USERNAME` is the username of the Apple Account.
- `WWDRTeamID` is the developer/team ID available from the Apple Account.
- `secret_2FA_Password` is the app-specific password you set up in the first step.
3. Periodically execute the following to check the progress of the notarisation:
```
xcrun altool --eval-info <the long UUID string> -u <your Apple id>
````
4. If that returns success, staple the notarization to the dmg:
```
xcrun stapler staple <name of the .dmg>
```
- [This StackOverflow thread contains invaluable information about how to successfully notarize jpackage-based software](https://stackoverflow.com/questions/60953329/code-signing-notarization-using-jpackage-utility-isnt-working-on-macos)
## Things I know about Apple Signing Keys
- It is always OK to refer to the key by it's sha256 fingerprint, that works in every command

View File

@@ -9,7 +9,11 @@ JPackage scripts for packaging I2P on a Mac.
### Building
1. See [BUILD.md](BUILD.md)
1. Clone `i2p.i2p` as a sibling to this module
1. Build it with `ant clean preppkg-osx-only`
1. Set the `I2P_SIGNER` environment variable to a string identifying the signer.
1. Set the `I2P_BUILD_NUMBER` environment variable to some integer >= 1
1. Run `build.sh`
### How does it work
@@ -20,3 +24,22 @@ In order to build an AppBundle that can work from anywhere, it is necessary to u
1. Copies the contents of `../i2p.i2p/pkg-temp` inside the AppBundle, except for the `jars` directory
1. Signs the AppBundle
1. Invokes JPackage again to build the final .dmg
### Notarization
1. You need an "app-specific password" which you can create at https://appleid.apple.com
2. Execute
```
xcrun altool --eval-app --primary-bundle-id net.i2p.router -u <your Apple id> -f <name of the .dmg file>
```
This will ask you for the password you generated in step 1 and will return a long UUID string you can use to check the progress.
3. Periodically execute the following to check the progress of the notarisation:
```
xcrun altool --eval-info <the long UUID string> -u <your Apple id>
````
4. If that returns success, staple the notarization to the dmg:
```
xcrun stapler staple <name of the .dmg>
```

164
build.sh
View File

@@ -1,29 +1,8 @@
#!/bin/bash
set -e
git pull --tags
git describe --tags `git rev-list --tags --max-count=1` || exit 1
export GITHUB_TAG=$(git describe --tags `git rev-list --tags --max-count=1` | sed 's|i2p||g' | tr -d a-z-)
if [ -z "$I2P_VERSION" ]; then
I2P_VERSION="i2p-$GITHUB_TAG"
fi
if echo "$I2P_VERSION" | grep -q '.\..\..'; then
if [ -z "$I2P_RELEASE_VERSION" ]; then
I2P_RELEASE_VERSION="$I2P_VERSION"
fi
else
if [ -z "$I2P_RELEASE_VERSION" ]; then
I2P_RELEASE_VERSION=$GITHUB_TAG
fi
fi
if [ -z "$I2P_BUILD_NUMBER" ]; then
I2P_BUILD_NUMBER=1
fi
if [ -f config.sh ]; then
. "config.sh"
. config.sh
fi
# old javas output version to stderr and don't support --version
@@ -40,15 +19,23 @@ if [ "$JAVA" -lt "16" ]; then
exit 1
fi
if [ -z "${JAVA_HOME}" ]; then
JAVA_HOME=$(/usr/libexec/java_home)
if [ -z "${I2P_SIGNER}" ]; then
echo "I2P_SIGNER variable not set, can't sign. Script will terminate after unsigned app-image generation"
exit 1
fi
if [ -z "$I2P_SIGNER_USERPHRASE" ]; then
I2P_SIGNER_USERPHRASE=$(security find-identity -v -p codesigning | head -n 1 | cut -d '"' -f 2)
echo "Warning: using automatically configured signer ID, make sure this is the one you want: $I2P_SIGNER_USERPHRASE"
echo "continuing in 10 seconds"
sleep 10
if [ -z ${I2P_VERSION} ]; then
echo "I2P_VERSION not set, aborting"
exit 1
fi
if [ -z ${I2P_BUILD_NUMBER} ]; then
echo "please set the I2P_BUILD_NUMBER variable to some integer >= 1"
exit 1
fi
if [ -z ${JAVA_HOME} ]; then
JAVA_HOME=$(/usr/libexec/java_home)
fi
echo "JAVA_HOME is $JAVA_HOME"
@@ -58,43 +45,16 @@ echo "cleaning"
ARCH=$(uname -m)
HERE=$PWD
I2P_SRC=$HERE/i2p.i2p-jpackage-mac/
I2P_SRC_BASE=$HERE/i2p.i2p/
rm -rf "$I2P_SRC"
if [ ! -d "$I2P_SRC_BASE" ]; then
git clone https://i2pgit.org/i2p-hackers/i2p.i2p "$I2P_SRC_BASE"
fi
cd "$I2P_SRC_BASE" && git pull --tags && cd "$HERE"
git clone -b "$I2P_VERSION" "$I2P_SRC_BASE" "$I2P_SRC"
I2P_JARS=$HERE/i2p.i2p-jpackage-mac/pkg-temp/lib
I2P_PKG=$HERE/i2p.i2p-jpackage-mac/pkg-temp
cd "$I2P_SRC"
OLDEXTRA=$(grep 'String EXTRA' "$I2P_SRC/router/java/src/net/i2p/router/RouterVersion.java")
if [ -z "$EXTRA" ]; then
export EXTRACODE="mac"
export EXTRA=" public final static String EXTRA = \"-$EXTRACODE\";"
fi
sed -i.bak "s|$OLDEXTRA|$EXTRA|g" "$I2P_SRC/router/java/src/net/i2p/router/RouterVersion.java"
git commit -am "$I2P_RELEASE_VERSION-$EXTRACODE"
git checkout -b "$I2P_RELEASE_VERSION-$EXTRACODE" || git checkout "$I2P_RELEASE_VERSION-$EXTRACODE"
git archive --format=tar.gz --output="$HERE/i2p.i2p.jpackage-mac.tar.gz" "$I2P_RELEASE_VERSION-$EXTRACODE"
if [ ! -d "$I2P_PKG" ]; then
ant clean preppkg-osx-only
fi
cd "$HERE"
I2P_JARS=$HERE/../i2p.i2p/pkg-temp/lib
I2P_PKG=$HERE/../i2p.i2p/pkg-temp
mkdir build
echo "compiling custom launcher and update processor"
cc -v -Wl,-lobjc -mmacosx-version-min=10.9 -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -Ic -o build/libMacLauncher.jnilib -shared c/net_i2p_router_MacLauncher.c
cp "$I2P_JARS"/*.jar build
cp $I2P_JARS/*.jar build
cd java
javac -d ../build -classpath ../build/i2p.jar:../build/router.jar net/i2p/router/MacLauncher.java net/i2p/update/*.java
cd "$HERE"
cd ..
echo "copying mac-update.sh"
cp bash/mac-update.sh build
@@ -104,16 +64,32 @@ cd build
jar -cf launcher.jar net mac-update.sh
cd ..
echo "preparing to invoke jpackage for I2P version $I2P_RELEASE_VERSION build $I2P_BUILD_NUMBER"
echo "compiling native lib"
cc -v -Wl,-lobjc -mmacosx-version-min=10.9 -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -Ic -o build/libMacLauncher.jnilib -shared c/net_i2p_router_MacLauncher.c
echo "signing jbigi libs"
mkdir jbigi
cp $I2P_JARS/jbigi.jar jbigi
cd jbigi
unzip jbigi.jar
for lib in *.jnilib; do
codesign --force -s $I2P_SIGNER -v $lib
jar uf jbigi.jar $lib
done
cp jbigi.jar ../build
cd ..
I2P_VERSION=$(java -cp build/router.jar net.i2p.router.RouterVersion | sed "s/.*: //" | head -n 1)
echo "preparing to invoke jpackage for I2P version $I2P_VERSION build $I2P_BUILD_NUMBER"
cp "$I2P_PKG/Start I2P Router.app/Contents/Resources/i2p.icns" build/I2P.icns
cp "$I2P_PKG/Start I2P Router.app/Contents/Resources/i2p.icns" build/I2P-volume.icns
cp "$I2P_PKG/LICENSE.txt" build
cp $I2P_PKG/LICENSE.txt build
cat resources/License-JRE-snippet.txt >> build/LICENSE.txt
cp resources/I2P-background.tiff build
cp resources/Info.plist.template build/Info.plist
sed -i.bak "s/I2P_VERSION/$I2P_RELEASE_VERSION/g" build/Info.plist
sed -i.bak "s/I2P_VERSION/$I2P_VERSION/g" build/Info.plist
sed -i.bak "s/I2P_BUILD_NUMBER/$I2P_BUILD_NUMBER/g" build/Info.plist
cp resources/I2P-dmg-setup.scpt.template build/I2P-dmg-setup.scpt
@@ -121,10 +97,6 @@ sed -i.bak "s@__HERE__@${HERE}@g" build/I2P-dmg-setup.scpt
rm build/*.bak
if [ -z $I2P_SIGNER_USERPHRASE ]; then
SIGNING_ARG="--mac-signing-key-user-name $I2P_SIGNER_USERPHRASE"
fi
jpackage --name I2P \
--java-options "-Xmx512m" \
--java-options "--add-opens java.base/java.lang=ALL-UNNAMED" \
@@ -133,37 +105,47 @@ jpackage --name I2P \
--type app-image \
--verbose \
--resource-dir build \
$SIGNING_ARG \
--mac-entitlements resources/entitlements.xml \
--input build --main-jar launcher.jar --main-class net.i2p.router.MacLauncher
echo "adding pkg-temp to resources"
cp -R "$I2P_PKG"/* I2P.app/Contents/Resources
cp -R $I2P_PKG/* I2P.app/Contents/Resources
for i in i2prouter lib locale man wrapper.config eepget runplain.sh postinstall.sh osid; do
rm -rf I2P.app/Contents/Resources/$i
done
cp "$HERE"/resources/GPLv2+CE.txt I2P.app/Contents/Resources/licenses/LICENSE-JRE.txt
cp "$I2P_PKG"/licenses/* I2P.app/Contents/Resources/licenses/
cp "$HERE"/build/libMacLauncher.jnilib I2P.app/Contents/Resources
if [ "$ARCH" == "arm64" ]; then
cp "$HERE/resources/router.config.arm64" I2P.app/Contents/Resources/router.config
cp $HERE/resources/GPLv2+CE.txt I2P.app/Contents/Resources/licenses/LICENSE-JRE.txt
cp $I2P_PKG/licenses/* I2P.app/Contents/Resources/licenses/
cp $HERE/build/libMacLauncher.jnilib I2P.app/Contents/Resources
if [ $ARCH == "arm64" ]; then
cp $HERE/resources/router.config.arm64 I2P.app/Contents/Resources/router.config
else
cp "$HERE/resources/router.config" I2P.app/Contents/Resources
cp $HERE/resources/router.config I2P.app/Contents/Resources
fi
# consider there might be some reason to re-enable this if an external maintainer arrives
#cp "$HERE"/resources/*.crt I2P.app/Contents/Resources/certificates/router
cp $HERE/resources/*.crt I2P.app/Contents/Resources/certificates/router
jpackage --name I2P \
--java-options "-Xmx512m" \
--java-options "--add-opens java.base/java.lang=ALL-UNNAMED" \
--java-options "--add-opens java.base/sun.nio.fs=ALL-UNNAMED" \
--java-options "--add-opens java.base/java.nio=ALL-UNNAMED" \
--type dmg \
--verbose \
--resource-dir build \
$SIGNING_ARG \
--mac-entitlements resources/entitlements.xml \
--input build --main-jar launcher.jar --main-class net.i2p.router.MacLauncher
if [ -z $I2P_SIGNER ]; then
echo "I2P_SIGNER is unset, not proceeding to signing phase"
exit 0
fi
if [ $I2P_SIGNER = signer@mail.i2p]; then
echo "I2P_SIGNER is unset, not proceeding to signing phase"
exit 0
fi
echo "signing the runtime libraries"
find I2P.app -name *.dylib -exec codesign --force -s $I2P_SIGNER -v '{}' \;
find I2P.app -name *.jnilib -exec codesign --force -s $I2P_SIGNER -v '{}' \;
echo "signing the bundle"
codesign --force -d --deep -f \
--options=runtime \
--entitlements resources/entitlements.xml \
-s $I2P_SIGNER \
--verbose=4 \
I2P.app
jpackage --name I2P --app-image I2P.app --app-version $I2P_VERSION \
--verbose --temp tmp \
--license-file build/LICENSE.txt \
--resource-dir build
ls -lah I2P*.dmg
ls -lahd I2P*

View File

@@ -15,6 +15,6 @@ rm -rfv \
prngseed.rnd \
router.config \
wrapper.log \
./*.jar \
./*.exe \
./*.dmg
*.jar \
*.exe \
*.dmg

View File

@@ -1,39 +0,0 @@
#! /usr/bin/env sh
# Uncomment/Edit this line to include the signer in the config file
# I2P_SIGNER=JIHGFEDCBA
# Uncomment/Edit this line to include the code signer in the config file
# I2P_CODE_SIGNER=ABCDEFGHIJ
# Uncomment/Edit this line to include the phrase identifying the signer to jpackage in the config file
# I2P_SIGNER_USERPHRASE=3rd Party Mac Developer Application: John Smith (ABCDEFGHIJ)
# Uncomment/Edit this line to include the version number in the config file
I2P_VERSION=i2p-2.4.0
# Uncomment/Edit this line to change the version number that you pass to jpackage
I2P_RELEASE_VERSION=2.4.0
# Uncomment/Edit this line to include the build number in the config file
# I2P_BUILD_NUMBER=1
if [ -z "$I2P_SIGNER" ]; then
# This is the team ID of the Apple account associated with the app. It is used to sign the DMG.
# it is a unique ID which is a short, random-looking string.
# OR
# the sha256 fingerprint of the cert(recommended)
echo "I2P_SIGNER not set, signing will not work"
fi
if [ -z "$I2P_CODE_SIGNER" ]; then
# This is the code signing ID of the team associated with the Apple Account. it is used to sign the libraries.
# it is a unique ID which is a short, random-looking string.
# OR
# the sha256 fingerprint of the cert(recommended)
echo "I2P_CODE_SIGNER not set, signing will not work"
fi
if [ -z "$I2P_SIGNER_USERPHRASE" ]; then
# This is an the phrase identifying the third party developer(I2P) in the following form:
# 3rd Party Mac Developer Application: John Smith (ABCDEFGHIJ)
# OR
# the sha256 fingerprint of the cert(recommended)
echo "I2P_SIGNER_USERPHRASE not set, signing will not work"
fi

5
config.sh Normal file
View File

@@ -0,0 +1,5 @@
#! /usr/bin/env sh
I2P_SIGNER=signer@mail.i2p
I2P_VERSION=2.0.0
I2P_BUILD_NUMBER=1

View File

@@ -1,7 +0,0 @@
Unsigned Output of I2P Easy-Install for Mac
===========================================
This is an unsigned `.dmg` package of the Java I2P router.
It consists of an I2P router embedded in a customized launcher.
It has been an "Official" I2P package in the past, however it has been partially broken for many years due to issues with notarization on Mac OSX.
This is functioning package, which should be ready for signing and notarization by any party who is able.

View File

@@ -1,4 +0,0 @@
How to produce a Self-Signed Development Build of This Package
==============================================================
TODO: Explain this process, take screenshots.

View File

@@ -18,6 +18,7 @@ public class MacLauncher {
/** this is totally undocumented */
private static final String APP_PATH = "jpackage.app-path";
private static Router i2pRouter;
public static void main(String[] args) throws Exception {
String path = System.getProperty(APP_PATH,"unknown");
@@ -42,12 +43,30 @@ public class MacLauncher {
}
i2pRouter = new Router(System.getProperties());
Thread registrationThread = new Thread(REGISTER_UPP);
registrationThread.setName("UPP Registration");
registrationThread.setDaemon(true);
registrationThread.start();
RouterLaunch.main(args);
String arch = System.getProperty("os.arch");
if (arch.equals("aarch64")) {
changeSetting(i2pRouter, "router.newsURL", "http://tc73n4kivdroccekirco7rhgxdg5f3cjvbaapabupeyzrqwv5guq.b32.i2p/mac-arm64/stable/news.su3");
changeSetting(i2pRouter, "router.backupNewsURL", "http://dn3tvalnjz432qkqsvpfdqrwpqkw3ye4n4i2uyfr4jexvo3sp5ka.b32.i2p/news/mac-arm64/stable/news.su3");
} else {
changeSetting(i2pRouter, "router.newsURL", "http://tc73n4kivdroccekirco7rhgxdg5f3cjvbaapabupeyzrqwv5guq.b32.i2p/mac/stable/news.su3");
changeSetting(i2pRouter, "router.backupNewsURL", "http://dn3tvalnjz432qkqsvpfdqrwpqkw3ye4n4i2uyfr4jexvo3sp5ka.b32.i2p/news/mac/stable/news.su3");
}
i2pRouter.runRouter();
}
private static void changeSetting(Router i2pRouter, String key, String value){
String setting = i2pRouter.getConfigSetting(key);
if (setting == null) {
i2pRouter.saveConfig(key, value);
}
}
private static native void disableAppNap();

View File

@@ -1,19 +1,19 @@
#! /usr/bin/env sh
I2P_DATE=$(date +%Y-%m-%d)
I2P_DATE=`date +%Y-%m-%d`
if [ -z "${I2P_OS}" ]; then
if [ -z ${I2P_OS} ]; then
I2P_OS=mac
fi
if [ -z "${I2P_BRANCH}" ]; then
if [ -z ${I2P_BRANCH} ]; then
I2P_BRANCH=beta
fi
if [ -z "${I2P_DOWNLOAD}" ]; then
if [ -z ${I2P_DOWNLOAD} ]; then
echo "\$I2P_DOWNLOAD is not set, an HTTP download will not be added to releases.json"
sleep 5s
fi
if [ -z "${I2P_VERSION}" ]; then
if [ -z ${I2P_VERSION} ]; then
echo "\$I2P_VERSION not set, aborting"
exit 1
fi

View File

@@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIIFkzCCA3ugAwIBAgIIefINnsa4ZtswDQYJKoZIhvcNAQENBQAwUzEeMBwGA1UE
BxMVSTJQIEFub255bW91cyBOZXR3b3JrMQwwCgYDVQQKEwNJMlAxDDAKBgNVBAsT
A0kyUDEVMBMGA1UEAwwMemFiQG1haWwuaTJwMB4XDTE5MDQwMzEzMTIzNVoXDTI5
MDQwMzEzMTIzNVowUzEeMBwGA1UEBxMVSTJQIEFub255bW91cyBOZXR3b3JrMQww
CgYDVQQKEwNJMlAxDDAKBgNVBAsTA0kyUDEVMBMGA1UEAwwMemFiQG1haWwuaTJw
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvkm0/e9w6iZT25A7AapZ
t6c2SdHZZrkVHOQXpgCfO5WzCbHyCKykXh1adxBU7YW1FQW1c/QrW7CPPN1qXmjB
S9bKv/VGoTkv/JA21eD4m887Ygtdmmm+EKgvRxa0spj7pqYj1Nuz2OYyYS4AxhJf
aNQG0Y4WMq+8+GK0eXF+DixsjZFDwFmKrsa7/Me9wO0W/eEhMoNSM9OVaZzFTrb5
Qes+2mAlRnd6vmHvA44aJM2aqxFpNHCIK3Pa6guj7mp4FCBq884HSHg4K2mA7esS
Ym47U1A6K6+Twwg8RtHpqUZ/HANk2rhlKyqynOvQSQvzuY6jujAL73++uJMRYF5h
nhVlzfmR3ijctl4WT1u49PkfhX+e0vqgloWKIO/Cg3x4OD8OJeZZI6kA42Q3vN4g
I3ZnxwbW8X4iPzF1LyTWMx6ABmEB4DBjlIk09TUYxt4grcUlYarOxfQkATyp+tMf
NjwvfWzU0766RVaIjvwA4zFSmzorRPSLEHwOc8SUz/ndTbZr88gt8ig5soEtsy+6
wGfKuxkvMrlcRRlJ0EVeRISeEZTV3cO7jo1Me7GgGk09aw0O701tzmnVJhqU0yi9
zxJeEoPWEazTPukk4qx/3p2pnQFp2z3tIphPuu/vMN+SZzOP0bvPtiepgDdJcRIf
WmZIHQ+mnyafplg8i+CLg6ECAwEAAaNrMGkwHQYDVR0OBBYEFHu2zaewzgpognLi
D8TJmXo5j47DMB8GA1UdIwQYMBaAFHu2zaewzgpognLiD8TJmXo5j47DMA4GA1Ud
DwEB/wQEAwIBpjAXBgNVHREEEDAOgQx6YWJAbWFpbC5pMnAwDQYJKoZIhvcNAQEN
BQADggIBABhISvTz6MJ/xqKklVxWrpWsbmtfCKewBQZBEVZLLwr2FEnC+CQl1wRT
yF5CwyOoz3MB+B2cmY8T45ffC9nVRf9AZzY9TyDFcJYkMFRGil1PrU1qjWK+MRh7
2R5KWrBZf709BmybcDZ8x6B2L94NivBjg7T+4B6bnkBkrZ6PQIsi2zbuM62uOF1v
xVLjwh3X7g4l6WmVubZFEOZ8QdPphhbCOrSufH6LFcKNVf5G52IaBSIvvOqPGzCl
2bYSCQ0q0QDkkVCJzfyupeX9ZBgNfKhx20r0oGcAMO55LEucqwDWNrcS5uvJpx+t
V+kNJUdgzZvNJfl5/2Y0FSqpZc0OOVq2b5vI7ZZmVOzo20NNjAg6Bme1Grwhbr4Z
ZuOmqHxxXpfVdIRVZ7iAVsBKTIMlo25MAYD+1BsN0uDq5K3kczqV8odMiAfVRkkX
E5xZgMsmjR9vn/nEpSMF5wT2IY0/w05hp9tnI1m8sPuu7wM9wPC/XXhxwa/8XFh4
lX29+kpi6W/WdnBFQfXX8f5bKDq2+q5MoSpz9s0WoIPWLDkQGPb9vs/Hw3vs8IJt
OdC6Uc1DawpGQhwiy0g+jmTjG8KSXCFeQv1u8q/yGIC2BAeor5y9HxsZq+6jvKtz
WNXTB3h5OC1YUiUOSvnvACeLSQSYc9qYM8yXM3TCJtX/tpEXrwNO
-----END CERTIFICATE-----