

# Generieren der Firmware-Aktualisierungsdatei und Signatur
<a name="lorawan-script-fwupdate-sigkey"></a>

Die Schritte in diesem Verfahren sind optional und hängen vom verwendeten Gateway ab. Gateway-Hersteller stellen ihr eigenes Firmware-Update in Form einer Aktualisierungsdatei oder eines Skripts bereit, und Basics Station führt dieses Skript im Hintergrund aus. In diesem Fall finden Sie die Firmware-Aktualisierungsdatei höchstwahrscheinlich in den Versionshinweisen des Gateways, das Sie verwenden. Sie können dann stattdessen diese Aktualisierungsdatei oder das Skript verwenden und mit dem Vorgang [Hochladen der Firmware-Datei in einen S3-Bucket und Hinzufügen einer IAM-Rolle](lorawan-upload-firmware-s3bucket.md) fortfahren.

Wenn Sie dieses Skript nicht haben, finden Sie im Folgenden die Befehle, die zum Generieren der Firmware-Aktualisierungsdatei ausgeführt werden müssen. Die Updates können auch signiert werden, um sicherzustellen, dass der Code nicht verändert oder beschädigt wurde und dass auf Geräten Code ausgeführt wird, der nur von vertrauenswürdigen Quellen veröffentlicht wurde.

**Topics**
+ [Generieren Sie die Firmware-Aktualisierungsdatei](#lorawan-firmware-update-script)
+ [Generieren Sie die Signatur für die Firmware-Aktualisierung](#lorawan-generate-signature-fwupdate)
+ [Überprüfen Sie die nächsten Schritte](#lorawan-fwupdate-sigkey-next-steps)

## Generieren Sie die Firmware-Aktualisierungsdatei
<a name="lorawan-firmware-update-script"></a>

Die LoRa Basics Station-Software, die auf dem Gateway läuft, kann Firmware-Updates in der CUPS-Antwort empfangen. Wenn Sie kein vom Hersteller bereitgestelltes Skript haben, lesen Sie das folgende Firmware-Aktualisierungsskript, das für das Raspberry Pi-basierte RAKWireless Gateway geschrieben wurde. Wir haben ein Basisskript und die neue Station-Binärdatei, die Versionsdatei und `station.conf` sind an diese angehängt.

**Anmerkung**  
Das Skript ist spezifisch für das RAKWireless Gateway, sodass Sie es je nach verwendetem Gateway an Ihre Anwendung anpassen müssen.

**Basis-Skripte**  
Im Folgenden finden Sie ein Beispiel-Basisskript für das auf Raspberry Pi-basierende RAKWireless Gateway. Sie können die folgenden Befehle in einer Datei `base.sh` speichern und das Skript dann im Terminal im Webbrowser des Raspberry Pi ausführen.

```
*#!/bin/bash*
execution_folder=/home/pi/Documents/basicstation/examples/aws_lorawan
station_path="$execution_folder/station"
version_path="$execution_folder/version.txt"
station_conf_path="$execution_folder/station_conf"

# Function to find the Basics Station binary at the end of this script 
# and store it in the station path
function prepare_station()
{
 match=$(grep --text --line-number '^STATION:$' $0 | cut -d ':' -f 1) 
 payload_start=$((match + 1)) 
 match_end=$(grep --text --line-number '^END_STATION:$' $0 | cut -d ':' -f 1) 
 payload_end=$((match_end - 1)) 
 lines=$(($payload_end-$payload_start+1)) 
 head -n $payload_end $0 | tail -n $lines  > $station_path
}

# Function to find the version.txt at the end of this script 
# and store it in the location for version.txt
function prepare_version()
{
  match=$(grep --text --line-number '^VERSION:$' $0 | cut -d ':' -f 1) 
  payload_start=$((match + 1))        
  match_end=$(grep --text --line-number '^END_VERSION:$' $0 | cut -d ':' -f 1) 
  payload_end=$((match_end - 1)) 
  lines=$(($payload_end-$payload_start+1)) 
  head -n $payload_end $0 | tail -n $lines  > $version_path
}

# Function to find the version.txt at the end of this script 
# and store it in the location for version.txt
function prepare_station_conf()
{
 match=$(grep --text --line-number '^CONF:$' $0 | cut -d ':' -f 1) 
 payload_start=$((match + 1)) 
 match_end=$(grep --text --line-number '^END_CONF:$' $0 | cut -d ':' -f 1) 
 payload_end=$((match_end - 1)) 
 lines=$(($payload_end-$payload_start+1)) 
 head -n $payload_end $0 | tail -n $lines  > $station_conf_path
}

# Stop the currently running Basics station so that it can be overwritten
# by the new one
killall station

# Store the different files
prepare_station
prepare_versionp
prepare_station_conf

# Provide execute permission for Basics station binary
chmod +x $station_path

# Remove update.bin so that it is not read again next time Basics station starts
rm -f /tmp/update.bin

# Exit so that rest of this script which has binaries attached does not get executed
exit 0
```

**Nutzlast-Skripte hinzufügen**  
An das Basisskript hängen wir die Basics Station-Binärdatei an, die Datei version.txt, die die Version identifiziert, auf die aktualisiert werden soll, und `station.conf` in einem Skript mit dem Namen `addpayload.sh`. Führen Sie dann dieses Skript aus.

```
*#!/bin/bash
*
base.sh > fwstation

# Add station
echo "STATION:" >> fwstation
cat $1 >> fwstation
echo "" >> fwstation
echo "END_STATION:" >> fwstation

# Add version.txt
echo "VERSION:" >> fwstation
cat $2 >> fwstation
echo "" >> fwstation
echo "END_VERSION:" >> fwstation

# Add station.conf
echo "CONF:" >> fwstation
cat $3 >> fwstation
echo "END_CONF:" >> fwstation

# executable
chmod +x fwstation
```

Nachdem Sie diese Skripts ausgeführt haben, können Sie den folgenden Befehl im Terminal ausführen, um die Firmware-Aktualisierungsdatei `fwstation` zu generieren.

```
$ ./addpayload.sh station version.txt station.conf
```

## Generieren Sie die Signatur für die Firmware-Aktualisierung
<a name="lorawan-generate-signature-fwupdate"></a>

Die LoRa Basics Station-Software bietet signierte Firmware-Updates mit ECDSA-Signaturen. Um signierte Updates zu unterstützen, benötigen Sie:
+ Eine Signatur, die mit einem privaten ECDSA-Schlüssel generiert werden muss und weniger als 128 Byte groß ist. 
+ Der private Schlüssel, der für die Signatur verwendet wird und im Gateway mit dem Dateinamen des Formats `sig-%d.key` gespeichert werden muss. Wir empfehlen, den Dateinamen `sig-0.key` zu verwenden.
+ Ein 32-Bit-CRC über dem privaten Schlüssel.

Die Signatur und der CRC werden an die AWS IoT Core für LoRaWAN-APIs übergeben. Um die vorherigen Dateien zu generieren, können Sie das folgende Skript `gen.sh` verwenden, das vom [Basicstation-Beispiel](https://github.com/lorabasics/basicstation/blob/master/examples/cups/prep.sh) im GitHub-Repository inspiriert ist.

```
*#!/bin/bash

*function ecdsaKey() {
    # Key not password protected for simplicity    
    openssl ecparam -name prime256v1 -genkey | openssl ec -out $1
}

# Generate ECDSA key
ecdsaKey sig-0.prime256v1.pem

# Generate public key
openssl ec -in sig-0.prime256v1.pem -pubout -out sig-0.prime256v1.pub

# Generate signature private key
openssl ec -in sig-0.prime256v1.pub -inform PEM -outform DER -pubin | tail -c 64 > sig-0.key

# Generate signature
openssl dgst -sha512 -sign sig-0.prime256v1.pem $1 > sig-0.signature

# Convert signature to base64
openssl enc -base64 -in sig-0.signature -out sig-0.signature.base64

# Print the crc
crc_res=$(crc32 sig-0.key)printf "The crc for the private key=%d\n" $((16#$crc_res))

# Remove the generated files which won't be needed later
rm -rf sig-0.prime256v1.pem sig-0.signature sig-0.prime256v1.pub
```

Der vom Skript generierte private Schlüssel sollte im Gateway gespeichert werden. Die Schlüsseldatei ist im Binärformat.

```
./gen_sig.sh fwstation 
read EC key
writing EC key
read EC key
writing EC key
read EC key
writing EC key
The crc for the private key=3434210794

$ cat sig-0.signature.base64 
MEQCIDPY/p2ssgXIPNCOgZr+NzeTLpX+WfBo5tYWbh5pQWN3AiBROen+XlIdMScv
AsfVfU/ZScJCalkVNZh4esyS8mNIgA==

$ ls sig-0.key
sig-0.key

$ scp sig-0.key pi@192.168.1.11:/home/pi/Documents/basicstation/examples/iotwireless
```

## Überprüfen Sie die nächsten Schritte
<a name="lorawan-fwupdate-sigkey-next-steps"></a>

Nachdem Sie die Firmware und Signatur generiert haben, fahren Sie mit dem nächsten Thema fort, `fwstation`, um die Firmware-Datei in einen Amazon–S3-Bucket hochzuladen. Der Bucket ist ein Container, in dem die Firmware-Aktualisierungsdatei als Objekt gespeichert wird. Sie können eine IAM-Rolle hinzufügen, die dem CUPS-Server die Erlaubnis erteilt, die Firmware-Aktualisierungsdatei im S3-Bucket zu lesen. 