Search Linux Wireless

[CRDA PATCH 1/6] Consolidate db signature validation in one function.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Both crda.c and dump.c had their own version of the code which
checks the validity of the signature on the regulatory db.
Having a common implementation shared by both files makes
maintenance easier and removes code duplication.

Signed-off-by: Davide Pesavento <davidepesa@xxxxxxxxx>
---
 Makefile |   14 ++++----
 crda.c   |  111 +---------------------------------------------------------
 dump.c   |  117 ++-----------------------------------------------------------
 regdb.c  |  119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 regdb.h  |    4 ++
 5 files changed, 134 insertions(+), 231 deletions(-)
 create mode 100644 regdb.c

diff --git a/Makefile b/Makefile
index 6d2faa6..69a2eba 100644
--- a/Makefile
+++ b/Makefile
@@ -17,23 +17,23 @@ INSTALL ?= install
 
 CRDA_LIB = "/usr/lib/crda/"
 
-all:	regulatory.bin warn crda
+all: regulatory.bin warn crda
 	@$(MAKE) --no-print-directory -f Makefile verify
 
 regulatory.bin:	db2bin.py key.priv.pem db.txt dbparse.py
 	@./db2bin.py regulatory.bin db.txt key.priv.pem
 
-crda: keys-gcrypt.c keys-ssl.c crda.c regdb.h
-	$(CC) $(CFLAGS) $(LDFLAGS) -lnl -o $@ crda.c
+crda: keys-ssl.c keys-gcrypt.c regdb.h regdb.o crda.o
+	$(CC) $(CFLAGS) $(LDFLAGS) -lnl -o $@ regdb.o crda.o
 
 clean:
-	@rm -f regulatory.bin dump *~ *.pyc keys-*.c crda
+	@rm -f regulatory.bin crda dump *.o *~ *.pyc keys-*.c
 	@if test -f key.priv.pem && diff -qNs test-key key.priv.pem >/dev/null ; then \
 	rm -f key.priv.pem;\
 	fi
 
 warn:
-	@if test !  -f key.priv.pem || diff -qNs test-key key.priv.pem >/dev/null ; then \
+	@if test ! -f key.priv.pem || diff -qNs test-key key.priv.pem >/dev/null ; then \
 	echo '**************************************';\
 	echo '**  WARNING!                        **';\
 	echo '**  No key found, using TEST key!   **';\
@@ -46,8 +46,8 @@ key.priv.pem:
 generate_key:
 	openssl genrsa -out key.priv.pem 2048
 
-dump:	dump.c regdb.h keys-ssl.c keys-gcrypt.c
-	$(CC) $(CFLAGS) $(LDFLAGS) dump.c -o dump
+dump: keys-ssl.c keys-gcrypt.c regdb.h regdb.o dump.o
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ regdb.o dump.o
 
 keys-ssl.c: key2pub.py $(wildcard *.pem)
 	@./key2pub.py --ssl *.pem > keys-ssl.c
diff --git a/crda.c b/crda.c
index b5e738f..cf493e8 100644
--- a/crda.c
+++ b/crda.c
@@ -21,21 +21,6 @@
 
 #include "regdb.h"
 
-#ifdef USE_OPENSSL
-#include <openssl/objects.h>
-#include <openssl/bn.h>
-#include <openssl/rsa.h>
-#include <openssl/sha.h>
-
-#include "keys-ssl.c"
-#endif
-
-#ifdef USE_GCRYPT
-#include <gcrypt.h>
-
-#include "keys-gcrypt.c"
-#endif
-
 struct nl80211_state {
 	struct nl_handle *nl_handle;
 	struct nl_cache *nl_cache;
@@ -199,18 +184,6 @@ int main(int argc, char **argv)
 	struct nlattr *nl_reg_rules;
 	int num_rules;
 
-#ifdef USE_OPENSSL
-	RSA *rsa;
-	__u8 hash[SHA_DIGEST_LENGTH];
-	int ok = 0;
-#endif
-#ifdef USE_GCRYPT
-	gcry_mpi_t mpi_e, mpi_n;
-	gcry_sexp_t rsa, signature, data;
-	__u8 hash[20];
-	int ok = 0;
-#endif
-
 	const char regdb[] = "/usr/lib/crda/regulatory.bin";
 
 	if (argc != 1) {
@@ -274,90 +247,8 @@ int main(int argc, char **argv)
 	}
 
 	/* verify signature */
-#ifdef USE_OPENSSL
-	rsa = RSA_new();
-	if (!rsa) {
-		fprintf(stderr, "Failed to create RSA key\n");
-		return -EINVAL;
-	}
-
-	if (SHA1(db, dblen, hash) != hash) {
-		fprintf(stderr, "Failed to calculate SHA sum\n");
-		RSA_free(rsa);
-		return -EINVAL;
-	}
-
-	for (i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) {
-		rsa->e = &keys[i].e;
-		rsa->n = &keys[i].n;
-
-		if (RSA_size(rsa) != siglen)
-			continue;
-
-		ok = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH,
-				db + dblen, siglen, rsa) == 1;
-		if (ok)
-			break;
-	}
-
-	rsa->e = NULL;
-	rsa->n = NULL;
-	RSA_free(rsa);
-
-	if (!ok) {
-		fprintf(stderr, "Database signature wrong\n");
+	if (!crda_verify_db_signature(db, dblen, siglen))
 		return -EINVAL;
-	}
-
-	BN_print_fp(stdout, &keys[0].n);
-#endif
-
-#ifdef USE_GCRYPT
-	/* initialise */
-	gcry_check_version(NULL);
-
-	/* hash the db */
-	gcry_md_hash_buffer(GCRY_MD_SHA1, hash, db, dblen);
-
-	if (gcry_sexp_build(&data, NULL, "(data (flags pkcs1) (hash sha1 %b))",
-			    20, hash)) {
-		fprintf(stderr, "failed to build data expression\n");
-		return 2;
-	}
-
-	if (gcry_sexp_build(&signature, NULL, "(sig-val (rsa (s %b)))",
-			    siglen, db + dblen)) {
-		fprintf(stderr, "failed to build signature expression\n");
-		return 2;
-	}
-
-	for (i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) {
-		if (gcry_mpi_scan(&mpi_e, GCRYMPI_FMT_USG,
-				  keys[0].e, keys[0].len_e, NULL) ||
-		    gcry_mpi_scan(&mpi_n, GCRYMPI_FMT_USG,
-		    		  keys[0].n, keys[0].len_n, NULL)) {
-			fprintf(stderr, "failed to convert numbers\n");
-			return 2;
-		}
-
-		if (gcry_sexp_build(&rsa, NULL,
-				    "(public-key (rsa (n %m) (e %m)))",
-				    mpi_n, mpi_e)) {
-			fprintf(stderr, "failed to build rsa key\n");
-			return 2;
-		}
-
-		if (!gcry_pk_verify(signature, data, rsa)) {
-			ok = 1;
-			break;
-		}
-	}
-
-	if (!ok) {
-		fprintf(stderr, "Database signature wrong\n");
-		return 2;
-	}
-#endif
 
 	num_countries = ntohl(header->reg_country_num);
 	countries = get_file_ptr(db, dblen,
diff --git a/dump.c b/dump.c
index b133915..89f16b2 100644
--- a/dump.c
+++ b/dump.c
@@ -1,29 +1,13 @@
+#include <errno.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/mman.h>
-#include <sys/types.h>
 #include <sys/stat.h>
-#include <unistd.h>
 #include <fcntl.h>
 #include <arpa/inet.h> /* ntohl */
 
 #include "regdb.h"
 
-#ifdef USE_OPENSSL
-#include <openssl/objects.h>
-#include <openssl/bn.h>
-#include <openssl/rsa.h>
-#include <openssl/sha.h>
-
-#include "keys-ssl.c"
-#endif
-
-#ifdef USE_GCRYPT
-#include <gcrypt.h>
-
-#include "keys-gcrypt.c"
-#endif
-
 static void *get_file_ptr(__u8 *db, int dblen, int structlen, __be32 ptr)
 {
 	__u32 p = ntohl(ptr);
@@ -95,17 +79,6 @@ int main(int argc, char **argv)
 	struct regdb_file_header *header;
 	struct regdb_file_reg_country *countries;
 	int dblen, siglen, num_countries, i, j;
-#ifdef USE_OPENSSL
-	RSA *rsa;
-	__u8 hash[SHA_DIGEST_LENGTH];
-	int ok = 0;
-#endif
-#ifdef USE_GCRYPT
-	gcry_mpi_t mpi_e, mpi_n;
-	gcry_sexp_t rsa, signature, data;
-	__u8 hash[20];
-	int ok = 0;
-#endif
 
 	if (argc != 2) {
 		fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
@@ -153,92 +126,8 @@ int main(int argc, char **argv)
 	}
 
 	/* verify signature */
-#ifdef USE_OPENSSL
-	rsa = RSA_new();
-	if (!rsa) {
-		fprintf(stderr, "Failed to create RSA key\n");
-		return 2;
-	}
-
-	if (SHA1(db, dblen, hash) != hash) {
-		fprintf(stderr, "Failed to calculate SHA sum\n");
-		return 2;
-	}
-
-	for (i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) {
-		rsa->e = &keys[i].e;
-		rsa->n = &keys[i].n;
-
-		if (RSA_size(rsa) != siglen)
-			continue;
-
-		ok = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH,
-				db + dblen, siglen, rsa) == 1;
-		if (ok)
-			break;
-	}
-
-	if (!ok) {
-		fprintf(stderr, "Database signature wrong\n");
-		return 2;
-	}
-
-	rsa->e = NULL;
-	rsa->n = NULL;
-	RSA_free(rsa);
-
-	BN_print_fp(stdout, &keys[0].n);
-
-	return 0;
-#endif
-
-#ifdef USE_GCRYPT
-	/* initialise */
-	gcry_check_version(NULL);
-
-	/* hash the db */
-	gcry_md_hash_buffer(GCRY_MD_SHA1, hash, db, dblen);
-
-	if (gcry_sexp_build(&data, NULL, "(data (flags pkcs1) (hash sha1 %b))",
-			    20, hash)) {
-		fprintf(stderr, "failed to build data expression\n");
-		return 2;
-	}
-
-	if (gcry_sexp_build(&signature, NULL, "(sig-val (rsa (s %b)))",
-			    siglen, db + dblen)) {
-		fprintf(stderr, "failed to build signature expression\n");
-		return 2;
-	}
-
-	for (i = 0; i < sizeof(keys)/sizeof(keys[0]); i++) {
-		if (gcry_mpi_scan(&mpi_e, GCRYMPI_FMT_USG,
-				  keys[0].e, keys[0].len_e, NULL) ||
-		    gcry_mpi_scan(&mpi_n, GCRYMPI_FMT_USG,
-		    		  keys[0].n, keys[0].len_n, NULL)) {
-			fprintf(stderr, "failed to convert numbers\n");
-			return 2;
-		}
-
-		if (gcry_sexp_build(&rsa, NULL,
-				    "(public-key (rsa (n %m) (e %m)))",
-				    mpi_n, mpi_e)) {
-			fprintf(stderr, "failed to build rsa key\n");
-			return 2;
-		}
-
-		if (!gcry_pk_verify(signature, data, rsa)) {
-			ok = 1;
-			break;
-		}
-	}
-
-	if (!ok) {
-		fprintf(stderr, "Database signature wrong\n");
-		return 2;
-	}
-
-#endif
+	if (!crda_verify_db_signature(db, dblen, siglen))
+		return -EINVAL;
 
 	num_countries = ntohl(header->reg_country_num);
 	countries = get_file_ptr(db, dblen,
diff --git a/regdb.c b/regdb.c
new file mode 100644
index 0000000..385ba7d
--- /dev/null
+++ b/regdb.c
@@ -0,0 +1,119 @@
+#ifdef USE_OPENSSL
+#include <stdio.h>
+#include <openssl/objects.h>
+#include <openssl/rsa.h>
+#include <openssl/sha.h>
+#endif
+
+#ifdef USE_GCRYPT
+#include <stdio.h>
+#include <gcrypt.h>
+#endif
+
+#include "regdb.h"
+
+#ifdef USE_OPENSSL
+#include "keys-ssl.c"
+#endif
+
+#ifdef USE_GCRYPT
+#include "keys-gcrypt.c"
+#endif
+
+/*
+ * Checks the validity of the signature found on the regulatory
+ * database against the array 'keys'. Returns 1 if there exists
+ * at least one key in the array such that the signature is valid
+ * against that key; 0 otherwise.
+ */
+int crda_verify_db_signature(__u8 *db, int dblen, int siglen)
+{
+#ifdef USE_OPENSSL
+	RSA *rsa;
+	__u8 hash[SHA_DIGEST_LENGTH];
+	unsigned int i;
+	int ok = 0;
+
+	rsa = RSA_new();
+	if (!rsa) {
+		fprintf(stderr, "Failed to create RSA key.\n");
+		goto out;
+	}
+
+	if (SHA1(db, dblen, hash) != hash) {
+		fprintf(stderr, "Failed to calculate SHA1 sum.\n");
+		RSA_free(rsa);
+		goto out;
+	}
+
+	for (i = 0; (i < sizeof(keys)/sizeof(keys[0])) && (!ok); i++) {
+		rsa->e = &keys[i].e;
+		rsa->n = &keys[i].n;
+
+		if (RSA_size(rsa) != siglen)
+			continue;
+
+		ok = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH,
+				db + dblen, siglen, rsa) == 1;
+	}
+
+	rsa->e = NULL;
+	rsa->n = NULL;
+	RSA_free(rsa);
+#endif
+
+#ifdef USE_GCRYPT
+	gcry_mpi_t mpi_e, mpi_n;
+	gcry_sexp_t rsa, signature, data;
+	__u8 hash[20];
+	unsigned int i;
+	int ok = 0;
+
+	/* initialise */
+	gcry_check_version(NULL);
+
+	/* hash the db */
+	gcry_md_hash_buffer(GCRY_MD_SHA1, hash, db, dblen);
+
+	if (gcry_sexp_build(&data, NULL, "(data (flags pkcs1) (hash sha1 %b))",
+			    20, hash)) {
+		fprintf(stderr, "Failed to build data S-expression.\n");
+		goto out;
+	}
+
+	if (gcry_sexp_build(&signature, NULL, "(sig-val (rsa (s %b)))",
+			    siglen, db + dblen)) {
+		fprintf(stderr, "Failed to build signature S-expression.\n");
+		goto out;
+	}
+
+	for (i = 0; (i < sizeof(keys)/sizeof(keys[0])) && (!ok); i++) {
+		if (gcry_mpi_scan(&mpi_e, GCRYMPI_FMT_USG,
+				keys[0].e, keys[0].len_e, NULL) ||
+		    gcry_mpi_scan(&mpi_n, GCRYMPI_FMT_USG,
+				keys[0].n, keys[0].len_n, NULL)) {
+			fprintf(stderr, "Failed to convert numbers.\n");
+			goto out;
+		}
+
+		if (gcry_sexp_build(&rsa, NULL,
+				    "(public-key (rsa (n %m) (e %m)))",
+				    mpi_n, mpi_e)) {
+			fprintf(stderr, "Failed to build RSA S-expression.\n");
+			goto out;
+		}
+
+		ok = gcry_pk_verify(signature, data, rsa) == 0;
+	}
+#endif
+
+#if defined(USE_OPENSSL) || defined(USE_GCRYPT)
+	if (!ok)
+		fprintf(stderr, "Database signature verification failed.\n");
+
+out:
+	return ok;
+#else
+	return 1;
+#endif
+}
diff --git a/regdb.h b/regdb.h
index 09cc403..bee00a5 100644
--- a/regdb.h
+++ b/regdb.h
@@ -100,6 +100,10 @@ struct regdb_file_reg_country {
 };
 
 
+/* functions */
+int crda_verify_db_signature(__u8 *db, int dblen, int siglen);
+
+
 /*
  * Verify that no unexpected padding is added to structures
  * for some reason.
-- 
1.6.0.2

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux