123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- From: Johannes Berg <johannes.berg@intel.com>
- Date: Mon, 9 Oct 2017 11:50:57 +0200
- Subject: [PATCH] regdb: write firmware file format (version code 20)
- TODO: clean up the Makefile stuff ...
- Signed-off-by: Johannes Berg <johannes.berg@intel.com>
- ---
- create mode 100755 db2fw.py
- --- a/Makefile
- +++ b/Makefile
- @@ -1,7 +1,5 @@
- # Install prefix
- PREFIX ?= /usr
- -CRDA_PATH ?= $(PREFIX)/lib/crda
- -CRDA_KEY_PATH ?= $(CRDA_PATH)/pubkeys
-
- MANDIR ?= $(PREFIX)/share/man/
-
- @@ -30,39 +28,47 @@ REGDB_AUTHOR ?= $(shell if [ -f $(DISTRO
- fi)
-
- REGDB_PRIVKEY ?= ~/.wireless-regdb-$(REGDB_AUTHOR).key.priv.pem
- -REGDB_PUBKEY ?= $(REGDB_AUTHOR).key.pub.pem
- -
- -REGDB_UPSTREAM_PUBKEY ?= sforshee.key.pub.pem
- +REGDB_PUBCERT ?= $(REGDB_AUTHOR).x509.pem
-
- REGDB_CHANGED = $(shell $(SHA1SUM) -c --status sha1sum.txt >/dev/null 2>&1; \
- if [ $$? -ne 0 ]; then \
- - echo maintainer-clean $(REGDB_PUBKEY); \
- + echo maintainer-clean $(REGDB_PUBCERT); \
- fi)
-
- .PHONY: all clean mrproper install maintainer-clean install-distro-key
-
- -all: $(REGDB_CHANGED) regulatory.bin sha1sum.txt
- +all: $(REGDB_CHANGED) regulatory.db.p7s sha1sum.txt
-
- clean:
- @rm -f *.pyc *.gz
-
- maintainer-clean: clean
- - @rm -f regulatory.bin
- + @rm -f regulatory.db regulatory.db.p7s
-
- mrproper: clean maintainer-clean
- - @echo Removed public key, regulatory.bin and compresed man pages
- - @rm -f $(REGDB_PUBKEY) .custom
- + @echo Removed public key, regulatory.db* and compressed man pages
- + @rm -f $(REGDB_PUBCERT) .custom
-
- -regulatory.bin: db.txt $(REGDB_PRIVKEY) $(REGDB_PUBKEY)
- - @echo Generating $@ digitally signed by $(REGDB_AUTHOR)...
- - ./db2bin.py regulatory.bin db.txt $(REGDB_PRIVKEY)
- +regulatory.db: db.txt db2fw.py
- + @echo "Generating $@"
- + ./db2fw.py regulatory.db db.txt
- +
- +regulatory.db.p7s: regulatory.db $(REGDB_PRIVKEY) $(REGDB_PUBCERT)
- + @echo "Signing regulatory.db (by $(REGDB_AUTHOR))..."
- + @openssl smime -sign \
- + -signer $(REGDB_PUBCERT) \
- + -inkey $(REGDB_PRIVKEY) \
- + -in $< -nosmimecap -binary \
- + -outform DER -out $@
-
- sha1sum.txt: db.txt
- sha1sum $< > $@
-
- -$(REGDB_PUBKEY): $(REGDB_PRIVKEY)
- - @echo "Generating public key for $(REGDB_AUTHOR)..."
- - openssl rsa -in $(REGDB_PRIVKEY) -out $(REGDB_PUBKEY) -pubout -outform PEM
- +$(REGDB_PUBCERT): $(REGDB_PRIVKEY)
- + @echo "Generating certificate for $(REGDB_AUTHOR)..."
- + @openssl req -config regulatory.openssl.conf \
- + -key $(REGDB_PRIVKEY) -days 36500 -utf8 -nodes -batch \
- + -x509 -outform PEM -out $(REGDB_PUBCERT)
- @echo $(REGDB_PUBKEY) > .custom
-
-
- @@ -97,16 +103,7 @@ install-distro-key: maintainer-clean $(D
- # make maintainer-clean
- # make
- # sudo make install
- -install: regulatory.bin.5.gz
- - install -m 755 -d $(DESTDIR)/$(CRDA_PATH)
- - install -m 755 -d $(DESTDIR)/$(CRDA_KEY_PATH)
- - if [ -f .custom ]; then \
- - install -m 644 -t $(DESTDIR)/$(CRDA_KEY_PATH)/ $(shell cat .custom); \
- - fi
- - install -m 644 -t $(DESTDIR)/$(CRDA_KEY_PATH)/ $(REGDB_UPSTREAM_PUBKEY)
- - install -m 644 -t $(DESTDIR)/$(CRDA_PATH)/ regulatory.bin
- +install: regulatory.db.5.gz
- + install -m 644 -t $(DESTDIR)/$(CRDA_PATH)/ regulatory.db
- install -m 755 -d $(DESTDIR)/$(MANDIR)/man5/
- - install -m 644 -t $(DESTDIR)/$(MANDIR)/man5/ regulatory.bin.5.gz
- -
- -uninstall:
- - rm -rf $(DESTDIR)/$(CRDA_PATH)/
- + install -m 644 -t $(DESTDIR)/$(MANDIR)/man5/ regulatory.db.5.gz
- --- a/README
- +++ b/README
- @@ -18,8 +18,8 @@ python module is used by the web viewer
- implemented as a MoinMoin macro (and used on http://wireless.kernel.org)
- to allow viewing the database for verification.
-
- -The dbparse module is also used by db2bin.py, the `compiler', which
- -compiles and signs the binary database.
- +The dbparse module is also used by db2bin.py and db2fw.py, the `compilers'
- +that compile the database to its binary formats.
-
- For more information, please see the CRDA git repository:
-
- --- /dev/null
- +++ b/db2fw.py
- @@ -0,0 +1,133 @@
- +#!/usr/bin/env python
- +
- +from cStringIO import StringIO
- +import struct
- +import hashlib
- +from dbparse import DBParser
- +import sys
- +
- +MAGIC = 0x52474442
- +VERSION = 20
- +
- +if len(sys.argv) < 3:
- + print 'Usage: %s output-file input-file' % sys.argv[0]
- + sys.exit(2)
- +
- +def create_rules(countries):
- + result = {}
- + for c in countries.itervalues():
- + for rule in c.permissions:
- + result[rule] = 1
- + return result.keys()
- +
- +def create_collections(countries):
- + result = {}
- + for c in countries.itervalues():
- + result[(c.permissions, c.dfs_region)] = 1
- + return result.keys()
- +
- +
- +def be32(output, val):
- + output.write(struct.pack('>I', val))
- +def be16(output, val):
- + output.write(struct.pack('>H', val))
- +
- +class PTR(object):
- + def __init__(self, output):
- + self._output = output
- + self._pos = output.tell()
- + be16(output, 0)
- + self._written = False
- +
- + def set(self, val=None):
- + if val is None:
- + val = self._output.tell()
- + assert val & 3 == 0
- + self._offset = val
- + pos = self._output.tell()
- + self._output.seek(self._pos)
- + be16(self._output, val >> 2)
- + self._output.seek(pos)
- + self._written = True
- +
- + def get(self):
- + return self._offset
- +
- + @property
- + def written(self):
- + return self._written
- +
- +p = DBParser()
- +countries = p.parse(file(sys.argv[2]))
- +rules = create_rules(countries)
- +rules.sort(cmp=lambda x, y: cmp(x.freqband, y.freqband))
- +collections = create_collections(countries)
- +collections.sort(cmp=lambda x, y: cmp(x[0][0].freqband, y[0][0].freqband))
- +
- +output = StringIO()
- +
- +# struct regdb_file_header
- +be32(output, MAGIC)
- +be32(output, VERSION)
- +
- +country_ptrs = {}
- +countrynames = countries.keys()
- +countrynames.sort()
- +for alpha2 in countrynames:
- + coll = countries[alpha2]
- + output.write(struct.pack('>cc', str(alpha2[0]), str(alpha2[1])))
- + country_ptrs[alpha2] = PTR(output)
- +output.write('\x00' * 4)
- +
- +reg_rules = {}
- +flags = 0
- +for reg_rule in rules:
- + freq_range, power_rule = reg_rule.freqband, reg_rule.power
- + reg_rules[reg_rule] = output.tell()
- + assert power_rule.max_ant_gain == 0
- + flags = 0
- + # convert to new rule flags
- + assert reg_rule.flags & ~0x899 == 0
- + if reg_rule.flags & 1<<0:
- + flags |= 1<<0
- + if reg_rule.flags & 1<<3:
- + flags |= 1<<1
- + if reg_rule.flags & 1<<4:
- + flags |= 1<<2
- + if reg_rule.flags & 1<<7:
- + flags |= 1<<3
- + if reg_rule.flags & 1<<11:
- + flags |= 1<<4
- + rule_len = 16
- + cac_timeout = 0 # TODO
- + if not (flags & 1<<2):
- + cac_timeout = 0
- + if cac_timeout:
- + rule_len += 2
- + output.write(struct.pack('>BBHIII', rule_len, flags, power_rule.max_eirp * 100,
- + freq_range.start * 1000, freq_range.end * 1000, freq_range.maxbw * 1000,
- + ))
- + if cac_timeout:
- + output.write(struct.pack('>H', cac_timeout))
- + while rule_len % 4:
- + output.write('\0')
- + rule_len += 1
- +
- +for coll in collections:
- + for alpha2 in countrynames:
- + if (countries[alpha2].permissions, countries[alpha2].dfs_region) == coll:
- + assert not country_ptrs[alpha2].written
- + country_ptrs[alpha2].set()
- + slen = 3
- + output.write(struct.pack('>BBBx', slen, len(list(coll[0])), coll[1]))
- + coll = list(coll[0])
- + for regrule in coll:
- + be16(output, reg_rules[regrule] >> 2)
- + if len(coll) % 2:
- + be16(output, 0)
- +
- +for alpha2 in countrynames:
- + assert country_ptrs[alpha2].written
- +
- +outfile = open(sys.argv[1], 'w')
- +outfile.write(output.getvalue())
|